当使用is特性切换不同的组件时,每次都会重新生成组件Vue实例并生成对应的VNode进行渲染,这样是比较花费性能的,而且切换重新显示时数据又会初始化,例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> </head> <body> <div id="app"> <button @click="currentComp=currentComp=='A'?'B':'A'">切换</button> <!--动态组件--> <component :is="currentComp"/> </div> <script> with(Vue.config){productionTip=false;devtools=false;} var app = new Vue({ el: '#app', components:{ A:{ template:"<div><input type='text'/></div>", name:'A', mounted:function(){console.log('Comp A mounted');} }, B:{ template:"<div>B组件</div>", name:'B', mounted:function(){console.log('Comp B mounted');} } }, data:{ currentComp:"A" } }) </script> </body> </html>
渲染结果为:
控制台输出:
当我们在输入框输入内容后再点击切换将切换到B组件后控制台输出:
然后再次点击切换,将显示A组件,此时控制台输出:
渲染出的A组件内容是空白的,我们之前在输入框输入的内容将没有了,这是因为使用is特性切换不同的组件时,每次都会重新生成组件Vue实例并生成对应的VNode进行渲染,数据会丢失的
解决办法是可以用Kepp-alive组件对子组件内的组件实例进行缓存,子组件激活时将不会再创建一个组件实例,而是从缓存里拿到组件实例,直接挂载即可,
使用keep-alive组件时,可以给该组件传递以下特性:
include ;只有名称匹配的组件会被缓存 ;只可以是字符串数组、字符串(以逗号分隔,分隔后每个内容就是要缓存的组件名)、正则表达式
exclude ;任何名称匹配的组件都不会被缓存 ;只可以是字符串数组、字符串(以逗号分隔,分隔后每个内容就是要缓存的组件名)、正则表达式
max ;数字。最多可以缓存多少组件实例
keep-alive对应的子组件有两个生命周期函数,这两个生命周期是keep-alive特有的,如下:
activated ;该子组件被激活时调用
deactivated ;该子组件被停用时调用
例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> </head> <body> <div id="app"> <button @click="currentComp=currentComp=='A'?'B':'A'">切换</button> <keep-alive> <component :is="currentComp"/> </keep-alive> </div> <script> with(Vue.config){productionTip=false;devtools=false;} var app = new Vue({ el: '#app', components:{ A:{ template:"<div><input type='text'/></div>", name:'A', mounted:function(){console.log('Comp A mounted');}, //挂载事件 activated:function(){console.log("Comp A activated");}, //激活时的事件,Kepp-alive独有的生命周期函数 deactivated:function(){console.log("Comp A deactivated");} //停用时的事件,Kepp-alive独有的生命周期函数 }, B:{ template:"<div>B组件</div>", name:'B', mounted:function(){console.log('Comp B mounted');}, activated:function(){console.log(&quo