浅入浅出 Vue 动态组件
浅入浅出居然出第二篇了,之前整理了一篇《浅入浅出 Vue 组件》,这次就再深入一点,学习一下动态组件。
什么是动态组件
简单的说,动态组件就是将几个组件放在一个挂载点下,然后根据父组件里某个变量来决定显示哪个,也可以都不显示。
语法
动态组件的核心就是挂载点,在挂载点会使用 <component>
标签,然后配合使用 v-bind:is="组件名"
,会自动去匹配组件名,有则显示,没有则不显示,也就是通过修改 is
指令的值,就可以改变挂载的组件。
1 | <!-- 组件会在 currentComponent 改变时改变 --> |
实例
说再多不如一个例子来得容易理解,根据介绍来看,最简单的场景就是 Tab 切换了,那我们先把基本界面搭出来。
在上面的界面里, Tab 内容区实际上就是组件的挂载点,那我们就把代码替换成:
1 | <!-- :tab="currentTab" 就是传入组件里的数据 --> |
接着我们准备 2 个 Tab 内容区的组件,同时注册好这 2 个组件:
1 | <!-- 为了做区分,这 2 个组件分别是展示 string 和 array 的数据 --> |
1 | Vue.component('tab-content-string', { |
再接着我们初始化一下这个 Vue 实例:
1 | <div id="app"> |
1 | var app = new Vue({ |
可以看到,在 data
数据里我定义了一个 currentTab
字段,并且实例在创建好后,将 tab[0]
的数据赋值给 currentTab
,这样可以将第一个 Tab 标签高亮,并显示出内容。
1 | created: function() { |
同时,在 Tab 标签上绑定一个点击事件,当点击触发后,将当前 Tab 标签的数据赋值给 currentTab
,这样在加载不同组件的时候,可以传入不同的数据。
1 | <a href="#" :class="{'active': currentTab == v}" v-for="v in tab" @click="currentTab = v">{{v.title}}</a> |
最后就是处理 v-bind:is="currentComponent"
,在 computed
里定义了 currentComponent()
这个方法,根据判断 currentTab.content
的类型,返回不同的组件名,实现动态组件的加载。
1 | computed: { |
来看下完整的效果:
keep-alive
当我们在动态切换这些组件的时候,可能会希望保留之前组件的状态,而不是每次切换后都是全新的界面。
打个比方,假设我们某个 Tab 内容里,又包了一个子 Tab ,就像下面这个演示一样:
我们会看到,当切换到 Tab2 的时候,里面是一个子 Tab ,默认显示在 Tab2-1 标签上,当我们对子 Tab 切换到第二个或者第三个标签后,切回到外层的 Tab1 标签再切换回来,会发现 Tab2 里的子 Tab 又回到第一个 Tab2-1 标签上了,这时候就是使用 keep-alive
的时候了。
使用 keep-alive
可以说是尤其简单,只需要用 <keep-alive>
标签将动态组件包裹起来就可以。
1 | <keep-alive> |
来看看效果如何:
没有问题,动态加载的组件被缓存了起来。