component
动态组件语法一般是配合is属性来实现的。在一个多标签的界面中使用is
来切换不同的组件
基础用法
Vue.component('home', {template: `<div>Home</div>`,
})
Vue.component('posts', {template: '<div>Posts</div>'
})
Vue.component('archive', {template: '<div>Archive</div>'
})
new Vue({el: '#app',data() {return {message: 'Hello Vue!',currentTabComponent: 'home',items: [{ id: 1, name: 'home' },{ id: 2, name: 'posts' },{ id: 3, name: 'archive'}],item:null}},methods: {changeMessage() {this.message = 'Goodbye Vue!';},showHandle(item){console.log("🚀 ~ showHandle ~ item:", item)this.currentTabComponent = item.namethis.item = item}},
})
<ul class="tab"><li @click="showHandle(item)" v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
<div><component :is="currentTabComponent"></component>
</div>
这样我们就实现了一个动态切换的组件
component
传参
一般我们都在组件上传很多自定义参数,在component
上面也是一样的操作
<div><component :is="currentTabComponent" :item="item"></component>
</div>
组件内跟接收普通props是一样的了
Vue.component('home', {props:{item:{type:Object,default(){return {}}}},template: `<div>Home<p>{{item}}</p></div>`,
})
component
组件的生命周期
Vue.component('home', {props:{item:{type:Object,default(){return {}}}},template: `<div>Home<p>{{item}}</p></div>`,created(){console.log("🚀 ~ created ~ item:", this.item)},mounted(){console.log("🚀 ~ mounted ~ item:", this.item)}
})
component
组件每次切换,都是重新渲染一遍组件,这样就会触发组件的所有生命周期
keep-alive
的使用
上面已经介绍了,使用component
组件进行切换时,会重新渲染整个组件,会丢失所有的状态,而keep-alive
组件就是我们为了保存状态而生。
<keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。
<!-- 失活的组件将会被缓存!-->
<keep-alive><component v-bind:is="currentTabComponent"></component>
</keep-alive>
这样,组件的切换就是display的属性在变化了,不会触发声明周期了。但是,有时候我们确实需要根据外部的某个prop进行数据或样式的变化怎么办?
当组件在 <keep-alive> 内被切换,它的
activated
和deactivated
这两个生命周期钩子函数将会被对应执行。
生命周期只会在初始化的时候加载一次,之后无论怎么切换,都不会出发created
及mounted
。
这样,我们也就可以实现组件内容的更新了。
- 三个属性
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max
- 数字。最多可以缓存多少组件实例。
主要用于保留组件状态或避免重新渲染。
<!-- 基本 -->
<keep-alive><component :is="view"></component>
</keep-alive><!-- 多个条件判断的子组件 -->
<keep-alive><comp-a v-if="a > 1"></comp-a><comp-b v-else></comp-b>
</keep-alive><!-- 和 `<transition>` 一起使用 -->
<transition><keep-alive><component :is="view"></component></keep-alive>
</transition>
注意, 是用在其一个直属的子组件被开关的情形。如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素, 要求同时只有一个子元素被渲染。
include
exclude
2.1.0 新增
include
和 exclude
允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:
<!-- 逗号分隔字符串 -->
<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>
- 匹配首先检查组件自身的 name 选项
- 如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。
- 匿名组件不能被匹配。
max
2.5.0 新增,最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
<keep-alive :max="10"><component :is="view"></component>
</keep-alive>