动态组件
有的时候,我们需要在多个不同的组件之间进行切换。虽然我们可以通过 v-if 来处理,但是会比较麻烦,vue
提供了一个更方便的方式来处理这种情况
一、component组件
component
是 vue
内置的一个组件,它提供一个 is
属性用来动态渲染不同的组件
1.1 v-if或v-show实现选项卡切换
使用v-if频繁切换会频繁创建和销毁组件,消耗内存;且不会记住组件里的一些已有状态,如checked选中;
使用v-show首次刷新就会创建所有组件,即使没有显示时DOM结构仍然存在,只是隐藏了,消耗内存;且不会记住组件里的一些已有状态,如checked选中;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.current {
background: yellow;
}
</style>
</head>
<body>
<div id="app">
<button @click="goto('InBox')" :class="{'current': currentComponent==='InBox'}">收邮件</button>
<button @click="goto('PostMail')" :class="{'current': currentComponent==='PostMail'}">发邮件</button>
<button @click="goto('RecycleBin')" :class="{'current': currentComponent==='RecycleBin'}">垃圾箱</button>
<hr>
<!-- 使用v-if频繁切换会频繁创建和销毁组件,消耗内存;且不会记住组件里的一些已有状态,如checked选中 -->
<!-- <in-box v-if="currentComponent==='InBox'"></in-box>
<post-mail v-if="currentComponent==='PostMail'"></post-mail>
<recycle-bin v-if="currentComponent==='RecycleBin'"></recycle-bin> -->
<!-- 使用v-show首次刷新就会创建所有组件,即使没有显示时DOM结构仍然存在,只是隐藏了,消耗内存;且不会记住组件里的一些已有状态,如checked选中 -->
<in-box v-show="currentComponent==='InBox'"></in-box>
<post-mail v-show="currentComponent==='PostMail'"></post-mail>
<recycle-bin v-show="currentComponent==='RecycleBin'"></recycle-bin>
</div>
<script src="./js/vue.js"></script>
<script>
const InBox = {
data() {
return {
items: [
'111111',
'22222222222',
'aaaaaaaa',
'3333333'
]
}
},
template: `
<div>
<ul>
<li v-for="item of items">
<input type="checkbox" />
{{item}}
</li>
</ul>
</div>
`,
created() {
console.log('InBox:created');
},
destroyed() {
console.log('InBox:destroyed');
}
}
const PostMail = {
template: `
<div>PostMail</div>
`,
created() {
console.log('PostMail:created');
},
destroyed() {
console.log('PostMail:destroyed');
}
}
const RecycleBin = {
template: `
<div>RecycleBin</div>
`,
created() {
console.log('RecycleBin:created');
},
destroyed() {
console.log('RecycleBin:destroyed');
}
}
let app = new Vue({
el: '#app',
data: {
currentComponent: 'InBox'
},
components: {
InBox,
PostMail,
RecycleBin
},
methods: {
goto(target) {
this.currentComponent = target;
}
}
});
</script>
</body>
</html>
1.2component组件实现选项卡切换
只使用动态组件component还是会频繁的创建和销毁组件,而且也无法记住checked选中等状态。需要使用到keep-alive才能解决问题
.....
<div id="app">
<button @click="goto('InBox')" :class="{'current': currentComponent==='InBox'}">收邮件</button>
<button @click="goto('PostMail')" :class="{'current': currentComponent==='PostMail'}">发邮件</button>
<button @click="goto('RecycleBin')" :class="{'current': currentComponent==='RecycleBin'}">垃圾箱</button>
<hr>
<component :is="currentComponent"></component>
</div>
.....
们会发现,当组件切换的时候,都会触发组件的销毁和重建。首先,性能不好。其次,会丢失组件状态
二、keep-alive组件
当在这些组件之间切换的时候,有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。keep-alive
是一个内置容器组件, 使用keep-alive
以后,内部包含的组件将增加 激活
和 失活/冻结
的状态
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
三、生命周期
使用了 keep-alive
的组件会触发 activated
、deactivated
两个生命周期函数
3.1 activated
keep-alive
组件激活时调用。
3.2 deactivated
keep-alive
组件停用时调用。
比如冻结时(如点击到其他选项卡时,将上一个选项卡的定时器销毁等)