1. 简介
uniapp 是一个基于 Vue.js 的跨平台开发框架,能够快速地开发出可以同时运行于多个平台的应用程序。同时,uniapp 还支持动态创建和删减页面的能力。在某些业务场景下,我们可能需要动态地添加或删减页面的组件,uniapp 提供了非常便捷的解决方案。
2. 动态添加 View
2.1 创建一个 Vue 组件
首先,我们需要创建一个 Vue 组件,这个组件将会被动态插入到父组件中。我们在新建一个 add-component.vue 文件,并编写如下代码:
<template>
<div class="add-component">
<button @click="addComponent">添加组件</button>
</div>
</template>
<script>
export default {
name: 'AddComponent',
methods: {
addComponent() {
const parent = this.$parent;
const componentInstance = new Vue({
render: h => h('div', '我是动态组件'),
});
componentInstance.$mount();
parent.$el.appendChild(componentInstance.$el);
},
},
};
</script>
<style scoped>
.add-component {
width: 100%;
text-align: center;
margin-top: 16px;
}
button {
background-color: #1989fa;
color: #fff;
font-size: 16px;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
outline: none;
}
</style>
以上代码中,我们创建了一个名为 AddComponent 的 Vue 组件,这个组件内部有一个按钮,当按钮被点击时,它将会在父组件中动态添加一个新的组件实例。 首先,通过 this.$parent 获取到当前组件的父级组件,然后使用 new Vue 的方式创建一个新的组件实例,设置该组件实例的 render 函数,这个函数返回了一个 div 标签,里面包含了文本 “我是动态组件”。
接下来,通过 $mount() 方法将组件实例挂载到 DOM 树上,然后通过 parent.$el.appendChild() 方法将组件实例的根节点添加到父组件的根节点中。
2.2 将组件添加到父组件中
首先,我们需要在父组件中引入“add-component”组件,然后在父组件中使用“add-component”组件,如下:
<template>
<div class="container">
<add-component />
</div>
</template>
<script>
import AddComponent from '@/components/add-component.vue';
export default {
name: 'Home',
components: {
AddComponent,
},
};
</script>
这时,我们在父组件中就可以使用组件中定义的 addComponent() 方法来动态添加组件了。
3. 动态删除 View
3.1 创建多个 Vue 组件
为了演示如何动态删除组件,我们首先需要创建多个组件。我们在新建一个 del-component.vue 文件,并编写如下代码:
<template>
<div class="del-component">
<button @click="removeComponent">移除组件</button>
<transition name="fade" v-if="visible">
<div>我是动态组件{{id}}</div>
</transition>
</div>
</template>
<script>
export default {
name: 'DelComponent',
props: {
id: {
type: Number,
required: true,
},
},
data() {
return {
visible: true,
};
},
methods: {
removeComponent() {
this.visible = false;
this.$emit('remove',this.id);
},
},
};
</script>
<style scoped>
.del-component {
width: 100%;
text-align: center;
margin-top: 16px;
}
button {
background-color: #1989fa;
color: #fff;
font-size: 16px;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
outline: none;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>
以上代码中,我们创建了一个名为 DelComponent 的 Vue 组件,这个组件内部有一个按钮,当按钮被点击时,它将会隐藏这个组件,并通过 $emit() 方法向父组件发送一个事件。这个组件还有一个 id 属性,用于在后面的例子中进行区分。
下面,我们在父组件中添加多个 DelComponent 组件:
<template>
<div class="container">
<div v-for="(component, index) in components" :key="component.id">
<del-component :id="component.id" @remove="removeComponent(index)" />
</div>
<button @click="addComponent">添加组件</button>
</div>
</template>
<script>
import DelComponent from '@/components/del-component.vue';
let id = 0;
export default {
name: 'Home',
components: {
DelComponent,
},
data() {
return {
components: [
{
id: id++,
},
{
id: id++,
},
],
};
},
methods: {
addComponent() {
this.components.push({
id: id++,
});
},
removeComponent(index) {
this.components.splice(index, 1);
},
},
};
</script>
<style scoped>
.container {
width: 100%;
text-align: center;
margin-top: 16px;
}
button {
background-color: #1989fa;
color: #fff;
font-size: 16px;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
outline: none;
}
</style>
以上代码中,我们在父组件中添加了多个 DelComponent 组件,每个组件传递了一个 id 属性,并且为组件设置了 remove 事件。在 addComponent() 方法中,我们向 components 数组中添加了一个新的对象,该对象包含了一个 id 属性。在 removeComponent() 方法中,我们通过组件传递过来的 index 参数删除了指定的组件。
3.2 移除组件
下面是一个例子,动态移除任意组件:
<template>
<div class="container">
<div v-for="(component, index) in components" :key="component.id">
<del-component :id="component.id" @remove="removeComponent(index)" />
</div>
</div>
</template>
<script>
import DelComponent from '@/components/del-component.vue';
let id = 0;
export default {
name: 'Home',
components: {
DelComponent,
},
data() {
return {
components: [
{
id: id++,
},
{
id: id++,
},
],
};
},
methods: {
addComponent() {
this.components.push({
id: id++,
});
},
removeComponent(index) {
this.components.splice(index, 1);
},
},
};
</script>
<style scoped>
.container {
width: 100%;
text-align: center;
margin-top: 16px;
}
</style>
以上代码中,我们在父组件中引入了 del-component 组件,并使用 v-for 指令创建了多个组件实例。当组件中的移除按钮被点击时,它将会隐藏自身并向父组件发送一个 remove 事件,父组件则会在 removeComponent() 方法中移除该组件。
4. 总结
通过本文的学习,我们了解了如何在 uniapp 中动态地添加和移除组件。对于需要频繁添加或移除组件的场景,这种方式可以很好地解决问题。但是,需要注意的是,当组件数量变得非常多时,动态添加或移除组件可能会影响页面的性能,需要谨慎使用。