目录
一. 什么是动态组件?
动态组件是指在一个挂载点使用多个组件,并进行动态切换。挂载点可以简单理解为页面的一个位置,最常见的应用场景是实现tab的切换功能。通过动态组件,可以根据不同的条件或事件,切换不同的组件来展示不同的内容。
所以其实通俗来讲,就是多个组件使用同一个挂载点,比如在tab切换中,点击tab下的不同目录,可以显示不同的组件。
目前可以实现这样的方法主要有三种,分别是<component>标签的is属性,v-if进行判断,以及v-show的判断,在这里我们将去讲解一下前两者的代码编写与逻辑。
二. v-if与<component>
1. v-if指令
v-if是Vue的一个内置指令,其切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件。
v-if 由false变为true时,触发组件的beforeCreate、create、beforeMount、mounter钩子,由true变为false时,触发组件的beforeDestory、destoryed方法。v-if 是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;v-if 也是惰性的,如果初始渲染时条件为假,则什么也不做——直到为真时才开始渲染条件块。
<template>
<div class="home">
<div class="left">
<ul>
<li v-for="item in list" :class="active==item.id?'active':''" @click="active=item.id">{{item.name}}</li>
</ul>
</div>
<div class="right">
<watch-page v-if="active==0"></watch-page>
<maodian-test v-if="active==1"></maodian-test>
<filters-test v-if="active==2"></filters-test>
<input-select-test v-if='active==3'></input-select-test>
<upload-test v-if="active==4"></upload-test>
<vue-lift-test v-if="active==5"></vue-lift-test>
</div>
</div>
</template>
<script>
import watchPage from './components/watchPage.vue'
import maodianTest from './components/maodian.vue'
import filtersTest from './components/filtersTest.vue'
import inputSelectTest from './components/inputSelectTest.vue'
import uploadTest from './components/uploadFileTest.vue'
import vueLiftTest from './components/vueLiftTest.vue'
export default {
components: {
watchPage,
maodianTest,
filtersTest,
inputSelectTest,
uploadTest,
vueLiftTest
},
data() {
return {
active: 0,
list: [{
id: 0,
name: '性能测试',
}, {
id: 1,
name: '锚点测试',
}, {
id: 2,
name: 'filters过滤',
}, {
id: 3,
name: '搜索输入'
}, {
id: 4,
name: '上传文件'
}, {
id:5,
name:'vue生命周期'
}]
}
},
}
</script>
<style lang="scss" scoped>
.home {
display: flex;
.left {
width: 500px;
}
.right {
width: 80%;
}
ul li {
height: 80px;
width: 300px;
text-align: center;
line-height: 80px;
background: #e2e2e2;
list-style-type: none;
cursor: pointer;
&.active {
background: #c9d6ff;
}
}
ul li:hover {
background: #c9d6ff;
}
}
</style>
![](https://i-blog.csdnimg.cn/blog_migrate/77ad8e8dc0bcc56574c459d1000d11b7.jpeg)
2. <component>标签
由于v-if的本质是不断地销毁与重新渲染,所以使用v-if会产生更高的切换消耗,因此当切换频繁的时候使用<component>标签会具有更高的性能。代码如下
<template>
<div class="home">
<div class="left">
<ul>
<li v-for="item in list" :class="active==item.id?'active':''" @click="active=item.id">{{item.name}}</li>
</ul>
</div>
<div class="right">
<component :is="comList[active]"></component>
<!-- <watch-page v-if="active==0"></watch-page>
<maodian-test v-if="active==1"></maodian-test>
<filters-test v-if="active==2"></filters-test>
<input-select-test v-if='active==3'></input-select-test>
<upload-test v-if="active==4"></upload-test>
<vue-lift-test v-if="active==5"></vue-lift-test> -->
</div>
</div>
</template>
<script>
import watchPage from './components/watchPage.vue'
import maodianTest from './components/maodian.vue'
import filtersTest from './components/filtersTest.vue'
import inputSelectTest from './components/inputSelectTest.vue'
import uploadTest from './components/uploadFileTest.vue'
import vueLiftTest from './components/vueLiftTest.vue'
export default {
components: {
watchPage,
maodianTest,
filtersTest,
inputSelectTest,
uploadTest,
vueLiftTest
},
data() {
return {
comList:['watchPage','maodianTest','filtersTest','inputSelectTest','uploadTest','vueLiftTest'],
active: 0,
list: [{
id: 0,
name: '性能测试',
}, {
id: 1,
name: '锚点测试',
}, {
id: 2,
name: 'filters过滤',
}, {
id: 3,
name: '搜索输入'
}, {
id: 4,
name: '上传文件'
}, {
id:5,
name:'vue生命周期'
}]
}
},
}
</script>
<style lang="scss" scoped>
.home {
display: flex;
.left {
width: 500px;
}
.right {
width: 80%;
}
ul li {
height: 80px;
width: 300px;
text-align: center;
line-height: 80px;
background: #e2e2e2;
list-style-type: none;
cursor: pointer;
&.active {
background: #c9d6ff;
}
}
ul li:hover {
background: #c9d6ff;
}
}
</style>
![](https://i-blog.csdnimg.cn/blog_migrate/923e13da82206e4b74163a4263656e21.jpeg)
三. keep-alive保存状态
1. keep-alive使用
还有一种比较常见的需求,比如当你在编辑表单,突然要去看一些别页面,这时候切换过去再切换过来,会发现先前编辑的表单数据全部消失了,这时候就只能重新编辑了,是不是很苦恼?别急,keep-alive就可以帮我们解决这个问题啦!
这里只要将<component>外嵌套一个<keep-alive>标签就好啦
<keep-alive>
<component :is="comList[active]"></component>
</keep-alive>
![](https://i-blog.csdnimg.cn/blog_migrate/4e6688026a625c3492530628170d5ea0.jpeg)
PS.
keep-alive有两个属性如下
include:指定需要被缓存的组件,没有指定的则不会被缓存
exclude:指定不需要被缓存的组件,没有指定则被缓存
比如在下面代码中,将不会缓存<inputSelectTest>组件的数据,这时候再上一张运行效果的图片中,输入数据再切换组件,然后切换回来,会发现之前填写的数据全都没了
<keep-alive exclude='inputSelectTest'>
<component :is="comList[active]"></component>
</keep-alive>
2. 两个生命周期钩子
在vue的生命周期中,有两个特殊的钩子函数,只有在使用<keep-alive>的时候才会起作用,就是activated()函数和deactivated()函数。
activated()函数是组件被激活的函数
deactivated()函数是组件被缓存的函数
使用代码如下
activated(){
console.log('组件被激活')
},
deactivated(){
console.log('组件被缓存')
}
四. 总结
动态组件是项目开发中很常见的一个实现方式,相信各位看官通过本文的讲解都一定有所收获吧!好记性不如烂笔头,有兴趣的小伙伴赶紧来实践操作下吧!最后附上本次项目的Gitee源码,有兴趣的可以下拉下来运行试一下哦~