Vue动态组件

举报
别团等shy哥发育 发表于 2023/02/04 11:53:23 2023/02/04
【摘要】 @toc 1、序言  在页面应用程序中,经常会遇到多标签页面,在Vue.js中,可以通过动态组件来实现。组件的动态切换是通过在<component>元素上使用is属性实现的。 2、实例  实现效果如下:  上图中的3个标签是3个按钮,下面的内容部分由组件来实现,3个按钮对应3个组件,按钮响应click事件,单机不同按钮时切换至不同的组件,组件切换通过<component>元素和其上的is属性...

@toc

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>

渲染结果:
在这里插入图片描述
修改
在这里插入图片描述
切换标签之后
在这里插入图片描述
  可以看到,组件的状态被保存了下来。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。