动态组件
这里我们要学习一个新的标签component,写在template模板中。它有一个属性is,is的属性值是字符串,值为我们想要显示组件。
写法:<component is="组件名"></component>
之前我们学v-if和v-show的时候,利用这个指令实现了tab栏切换。主要利用了排他思想,过程比较繁杂,这里学习了动态组件我们也可以利用它实现。
实现思路:创建三个子组件对应三个页面,导入父组件注册,当我们点击对应的按钮时将对应的组件名传入component标签的is属性中,实现对应组件在页面的渲染。
父组件实现代码:
<template>
<div class="app">
<div class="app1" v-for="(item, index) in arr" @click="fn(index)" :key="index">
{{item}}
</div>
<component :is="pagevalue[msg]"></component>
</div>
</template>
<script>
import Box1 from "@/components/box1.vue"
import Box2 from "@/components/box2.vue"
import Box3 from "@/components/box3.vue"
export default {
data() {
return {
pagevalue:["box1","box2","box3"],
arr:["按钮1","按钮2","按钮3"],
msg:"0"
}
},
methods: {
fn(index){
this.msg=index
}
},
components:{
Box1,
Box2,
Box3
},
}
</script>
<style>
.app{
position: relative;
width: 200px;
}
.app1{
position: relative;
top: 20px;
background-color: aquamarine;
display: inline-block;
width: 65px;
height: 30px;
text-align: center;
line-height: 30px;
cursor: pointer;
caret-color: transparent;
}
</style>
页面效果:点击按钮2时
即导航栏切换的功能就实现了。
缓存组件
通过这个案例我们来引入我们的缓存组件,首先我们要明白为什么要引入缓存组件,我们在通过动态组件时切换组件时,被切换掉的组件会被销毁掉,如果我们之前在这个页面还有数据也会被丢失,很明显这在实际产品中是不被允许的。
如何检测切换时组件是否被销毁,我们可以在box1组件中添加beforedestroy和created函数检验。
box1的script标签中添加代码:
<script>
export default{
created() {
console.log("box1被创建");
},
beforeDestroy() {
console.log("box1被销毁");
},
}
</script>
页面初次渲染时会打印一次“box1被创建”,当我们点击box2切换就会打印“box1被销毁”,再点击切回box1时又会打印“box1被创建”
控制台情况:
因此如果我们在box1有一个input标签,我们在输入值以后切换了页面后数据也会被删掉。
box1添加input标签如:
<template>
<div class="box1">
<h1>box1</h1>
<input type="text" v-model="msg" />
</div>
</template>
<script>
export default{
data() {
return {
msg:""
}
},
created() {
console.log("box1被创建");
},
beforeDestroy() {
console.log("box1被销毁");
},
}
</script>
<style>
.box1{
width: 200px;
height: 200px;
background-color: aqua;
margin-top: 0;
}
</style>
我们想要保留input的值,我们就需要利用组件缓存keep-alive标签,将要缓存的组件放在keep-alive标签内。在这里我们就是就是component标签放入其中。
<keep-alive></keep-alive>会默认把全部加载过的组件都会缓存起来。
如果想要改变,就需要用到它的三个属性之一
1、include 选择缓存哪些组件 可以写组件名字符串 也可以写正则;
2、exinclude 选择哪些组件不缓存;
3、max 最缓存几个,一旦设定的数值达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
这里我们就用include选择只缓存box1,修改父组件代码套上keep-alive标签:
<keep-alive include="box1">
<component :is="pagevalue[msg]"></component>
</keep-alive>
这个时候无论怎么切换box组件,box1标签内的value值都会被保存。
最后再介绍两个有关组件缓存的钩子函数activated和deactivated。
activated:只有当组件使用了组件缓存时,在该组件中activated钩子函数才会被调用,否则是无效的。首次加载组件时,运行在mounted页面挂载之后,但是当再次切回该组件页面时,created和mounted不会再执行,只会再执行actived。
我们在box1组件中测试一下就知道了,
box1添加代码:
created() {
console.log("created执行");
},
mounted() {
console.log("mounted执行");
},
activated() {
console.log("activated执行");
},
执行结果:
因此:我们运用了组件缓存时,如果想每次切换都发送一次请求的话,需要把请求函数写在activated中,而写在created或mounted中其只会在首次加载该组件的时候起作用。
deactivated:被 keep-alive 缓存的组件失活时调用。