zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Vue动态组件

Vue组件 动态
2023-06-13 09:17:20 时间

Vue动态组件

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>

渲染结果:

修改

切换标签之后

  可以看到,组件的状态被保存了下来。