Vue从入门到实战:动态组件
来自CloudWiki
在页面应用程序中,经常会遇到多标签页面,
在Vue.js中,可以通过动态组件来实现
组件的动态切换是通过在<component>元素上使用is属性来实现
三个标签是三个按钮,下面的内容部分由组件来实现,
三个按钮对应三个组件,按钮响应click事件,点击不同按钮时切换不同的组件,
组件切换通过<component>元素和其上的<a>属性来实现。
定义组件
Vue.component('tab-introduce', { data(){ return { content: 'Vue.js无难事' } }, template: '<div><input v-model="content"></div>' }) Vue.component('tab-comment', { template: '<div>这是一本好书</div>' }) Vue.component('tab-qa', { template: '<div>有人看过吗?怎么样?</div>' })
定义根实例
在根实例中定义了两个数据属性和一个计算属性,
主要是为了便于使用v-for指令循环渲染button按钮,以及动态切换组件。
var vm = new Vue({ el: '#app', data: { currentTab: 'introduce', tabs: [ {title: 'introduce', displayName: '图书介绍'}, {title: 'comment', displayName: '图书评价'}, {title: 'qa', displayName: '图书问答'} ] }, computed: { currentTabComponent: function () { return 'tab-' + this.currentTab } } })
在DOM中渲染
<div id="app"> <button v-for="tab in tabs" :key="tab.title" :class="['tab-button', { active: currentTab === tab.title }]" @click="currentTab = tab.title"> {{ tab.displayName }} </button> <!-- <keep-alive> --> <component v-bind:is="currentTabComponent" class="tab"> </component> <!-- </keep-alive> --> </div>
当点击某个标签按钮时,更改数据属性currentTab的值,这将导致计算属性currentTabComponent的值更新,
<component>元素的is属性使用v-bind指令绑定到一个已注册组件的名字上。
用keep-alive改进
如果希望组件在切换的时候,可以保持组件的状态,可以用一个<keep-alive>元素将动态组件包裹起来。
<keep-alive> <component v-bind:is="currentTabComponent" class="tab"> </component> </keep-alive>
完整代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>动态组件</title> <style> div { width: 400px; } .tab-button { padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: solid 1px #ccc; cursor: pointer; background: #f0f0f0; margin-bottom: -1px; margin-right: -1px; } .tab-button:hover { background: #e0e0e0; } .tab-button.active { background: #cdcdcd; } .tab { border: solid 1px #ccc; padding: 10px; } </style> </head> <body> <div id="app"> <button v-for="tab in tabs" :key="tab.title" :class="['tab-button', { active: currentTab === tab.title }]" @click="currentTab = tab.title"> {{ tab.displayName }} </button> <keep-alive> <component v-bind:is="currentTabComponent" class="tab"> </component> </keep-alive> </div> <script src="vue.js"></script> <script> Vue.component('tab-introduce', { data(){ return { content: 'Vue.js无难事' } }, template: '<div><input v-model="content"></div>' }) Vue.component('tab-comment', { template: '<div>这是一本好书</div>' }) Vue.component('tab-qa', { template: '<div>有人看过吗?怎么样?</div>' }) var vm = new Vue({ el: '#app', data: { currentTab: 'introduce', tabs: [ {title: 'introduce', displayName: '图书介绍'}, {title: 'comment', displayName: '图书评价'}, {title: 'qa', displayName: '图书问答'} ] }, computed: { currentTabComponent: function () { return 'tab-' + this.currentTab } } }) </script> </body> </html>