Vue动态组件
Vue动态组件
- 1、序言
- 2、实例
1、序言
在页面应用程序中,经常会遇到多标签页面,在Vue.js中,可以通过动态组件来实现。组件的动态切换是通过在<component>
元素上使用is
属性实现的。
2、实例
实现效果如下:
上图中的3个标签是3个按钮,下面的内容部分由组件来实现,3个按钮对应3个组件,按钮响应click事件,单机不同按钮时切换至不同的组件,组件切换通过<component>
元素和其上的is
属性实现。
3个组件的实现代码如下:
app.component('tab-introduce', {
data(){
return {
content: 'Java无难事'
}
},
template: '<div><input v-model="content"></div>'
})
app.component('tab-comment', {
template: '<div>这是一本好书</div>'
})
app.component('tab-qa', {
template: '<div>有人看过吗?怎么样?</div>'
})
第一个组件的模板使用了一个<input>
元素,便于我们修改内容,这主要是为了引出后面的知识点。
在根实例中定义了两个数据属性和一个计算属性,主要是为了便于使用v-for指令循环渲染button按钮,以及动态切换组件。代码如下所示:
const app = Vue.createApp({
data() {
return {
currentTab: 'introduce',
tabs: [
{ title: 'introduce', displayName: '图书介绍'},
{ title: 'comment', displayName: '图书评价'},
{ title: 'qa', displayName: '图书问答'}
]
}
},
computed: {
currentTabComponent: function () {
return 'tab-' + this.currentTab
}
}
})
数据属性currentTab代表当前的标签页,tabs是一个数组对象,通过v-for指令渲染代表标签的3个按钮,计算属性currentTabComponent代表当前选中的组件。
接下来就是在与实例关联的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 :is="currentTabComponent" class="tab">
</component>
</keep-alive>
</div>
当单击某个标签按钮时,更改数据属性currentTab的值,这将导致计算属性currentTabComponent的值更新,<component>
元素的is属性使用v-bind指令绑定到一个已注册的名字上,随着计算属性currentTabComponent值的改变,组件也就自动切换了。
剩下的就是CSS样式的设置了。完整的代码如下:
<!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 :is="currentTabComponent" class="tab">
</component>
</keep-alive>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script> const app = Vue.createApp({ data() { return { currentTab: 'introduce', tabs: [ { title: 'introduce', displayName: '图书介绍'}, { title: 'comment', displayName: '图书评价'}, { title: 'qa', displayName: '图书问答'} ] } }, computed: { currentTabComponent: function () { return 'tab-' + this.currentTab } } }) app.component('tab-introduce', { data(){ return { content: 'Java无难事' } }, template: '<div><input v-model="content"></div>' }) app.component('tab-comment', { template: '<div>这是一本好书</div>' }) app.component('tab-qa', { template: '<div>有人看过吗?怎么样?</div>' }) app.mount('#app'); </script>
</body>
</html>
上述代码中的第一个组件模板使用了一个<input>
元素,因此可以修改该组件的内容,修改后,切换到其他标签页,然后再切换回来,你会发现之前修改的内容并没有保存下来,这是因为每次切换新标签的时候,Vue都创建一个新的currentTabComponent实例。在本例中,希望组件在切换的时候,可以保持组件的状态,以避免重复渲染导致的性能问题,也为了让用户的体验更好。要解决这个问题,可以用一个<keep-alive>
元素将动态组件包裹起来。代码如下所示:
<keep-alive>
<component :is="currentTabComponent" class="tab">
</component>
</keep-alive>
渲染结果:
修改
切换标签之后
可以看到,组件的状态被保存了下来。
还没有评论,来说两句吧...