有的时候,在不同的组件之间进行动态的切换时非常有用的,比如在一个多标签的界面里:
上述内容可以通过 Vue 的 <component>
元素加一个特殊的 is
特性来实现:
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>
在上述示例中,currentTabComponent
可以包括:
- 已注册组件的名字
- 一个组件的选项对象
上示例: 首先是已注册组件的名字:
<div id="app">
<button @click="change">切换页面</button>
<component :is="currentTabComponent"></component>
</div>
Vue.component('home', {
template: '<div>Home component</div>',
});
Vue.component('posts', {
template: '<div>Posts component</div>',
});
Vue.component('archive', {
template: '<div>Archive component</div>',
});
new Vue({
el: '#app',
components: {
home,
post,
archive,
},
data:{
index:0,
arr:['home','post','archive'],
},
computed:{
currentTabComponent(){
return this.arr[this.index];
}
},
methods:{
change(){
this.index = (++this.index) % 3;
}
}
});
上示例: 然后是直接绑定到组件对象上:
<div id="app">
<button @click="change">切换页面</button>
<component :is="currentTabComponent"></component>
</div>
new Vue({
el: '#app',
data:{
index:0,
arr:[
{ template: `<div>Home component</div>` },
{ template: `<div>Posts component</div>` },
{ template: `<div>Archive component</div>` },
],
},
computed:{
currentTabComponent(){
return this.arr[this.index];
}
},
methods:{
change(){
this.index = (++this.index) % this.arr.length;
}
}
});
# 在动态组件上使用 keep-alive
当上述例子在组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。
可以假设,上述例子中的 home 页面内容中存在一个 输入框, 当你在输入框中输入内容后,点击其余页面后,再点击home页面时,希望自己输入的内容仍然保留。使用 keep-alive
可以更轻松的帮你实现这个效果。
<!-- 失活的组件将会被缓存!-->
<div id="app">
<button @click="change">切换页面</button>
<keep-alive>
<component :is="currentTabComponent"></component>
</keep-alive>
</div>
new Vue({
el: '#app',
data:{
index:0,
arr:[
{ template: `<div>Home component</div>` },
{ template: `<div>Posts component</div>` },
{ template: `<div>Archive component</div>` },
],
},
computed:{
currentTabComponent(){
return this.arr[this.index];
}
},
methods:{
change(){
this.index = (++this.index) % this.arr.length;
}
}
})
注意这个 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。
Props
: 给keep-alive
组件传递参数include
- 字符串或正则表达式或数组。只有名称匹配的组件会被缓存。exclude
- 字符串或正则表达式或数组。任何名称匹配的组件都不会被缓存max
- 数字。最多可以缓存多少组件实例
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
# 当存在多个条件性的子元素, 要求同时只能存在一个元素被渲染:
<div id="app">
<button @click="change">切换页面</button>
<keep-alive>
<home v-if="index === 0"></home>
<posts v-else-if="index === 1"></posts>
<archive v-else-if="index === 2"></archive>
</keep-alive>
</div>
new Vue({
el: '#app',
data:{
index:0,
arr:[
{ template: `<div>Home component</div>` },
{ template: `<div>Posts component</div>` },
{ template: `<div>Archive component</div>` },
],
},
computed:{
currentTabComponent(){
return this.arr[this.index];
}
},
methods:{
change(){
this.index = (++this.index) % this.arr.length;
}
}
})
# 当组件在 <keep-alive>
内被切换,它的 activated
和 deactivated
这两个生命周期钩子函数将会被对应执行:
在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 树内的所有嵌套组件中触发。
<div id="app">
<button @click="change">切换页面</button>
<keep-alive>
<component :is="currentTabComponent" @pass-data="getData"></component>
</keep-alive>
<p>{{msg}}</p>
</div>
new Vue({
el: '#app',
data:{
index:0,
msg:'',
arr:[
{
template:`<div>Home component</div>`,
activated(){
this.$emit('pass-data','触发activated');
},
deactivated(){
this.$emit('pass-data','触发deactivated');
},
},
{ template: `<div>Posts component</div>` },
{ template: `<div>Archive component</div>` },
],
},
computed:{
currentTabComponent(){
return this.arr[this.index];
},
},
methods:{
change(){
this.index = (++this.index) % this.arr.length;
},
getData(value){
this.msg = value;
setTimeout(()=>{
this.msg = '';
},500)
},
},
})
参考资料
来源:CSDN
作者:mjzy
链接:https://blog.csdn.net/weixin_42287935/article/details/103802784