vue内置组件的component标签

240 阅读2分钟

component官方说明

<component><slot> 和 <template> 具有类似组件的特性,也是模板语法的一部分。但它们并非真正的组件,同时在模板编译期间会被编译掉。因此,它们通常在模板中用小写字母书写。

image.png

通俗的讲,<component>就是渲染一个“元组件”为动态组件。按照 is 的值,来决定哪个组件被渲染。

component使用方式

使用方式很简单,只需要把想要显示的组件,放到 is 属性中就行,改变它props中的 is 属性就可以改变component中实际具体显示的组件内容。

image.png

image.png

项目应用

最近在封装左侧菜单栏的时候用到了component标签,通过在 is 属性中判断navList有无子节点,来决定具体显示的组件是<el-submenu>还是<el-menu-item>

image.png

代码片段

<template>
	<div class="left-tool">
		<el-menu unique-opened router :default-active="$route.path" class="left-menu" :collapse="leftMenu.isCollapse">
			<component class="menu-item" v-for="(value) in leftMenu.navList" :key="value.title+value.url"
				:index="value.url" :is="(value.children&&value.children.length>0)?'el-submenu':'el-menu-item'">
				<template slot="title">
					<i :class="[value.icon]"></i>
					<span>{{value.title}}</span>
				</template>
				<template v-if="value.children&&value.children.length>0">
					<el-menu-item class="menu-item" v-for="(v,i) in value.children" :key="v.url+i" @click="onChangePage(i,v.url)" :index="v.url">
						<!-- <i :class="[v.icon]"></i> -->
						<span slot="title">{{v.title}}</span>
					</el-menu-item>
				</template>
			</component>
		</el-menu>
	</div>
</template>
<script>
	export default {
		name: "LeftTool",
		data() {
			return {
				leftMenu: {
					isCollapse: false,
					navList: [{
						icon: 'el-icon-menu',
						title: '首页',
						url: '/home/home',
						children: [{
							icon: 'el-icon-tickets',
							title: '首页',
							url: '/home/home'
						}, {
							icon: 'el-icon-picture-outline',
							title: '隐私条款',
							url: '/home/privacy'
						}]
					}, {
						icon: 'el-icon-magic-stick',
						title: '效果选择',
						url: '/effect',
						children: [{
							icon: 'el-icon-tickets',
							title: '效果选择',
							url: '/effect/effect'
						}, {
							icon: 'el-icon-picture-outline',
							title: '页面配置',
							url: '/effect/effectDisposition'
						}]
					}, {
						icon: 'el-icon-picture-outline-round',
						title: '滤镜效果',
						url: '/filter/filter',
						children: [{
							icon: 'el-icon-tickets',
							title: '滤镜拍照',
							url: '/filter/filter'
						}, {
							icon: 'el-icon-picture-outline',
							title: '滤镜生成',
							url: '/filter/filterGenerate'
						}, {
							icon: 'el-icon-s-grid',
							title: '滤镜结果',
							url: '/filter/filterResult'
						}]
					}, {
						icon: 'el-icon-user',
						title: '人脸融合',
						url: '/faces/faces',
						children: [{
							icon: 'el-icon-tickets',
							title: '人脸融合风格选择',
							url: '/faces/faces'
						}, {
							icon: 'el-icon-picture-outline',
							title: '人脸融合拍照',
							url: '/faces/facesPhoto'
						}, {
							icon: 'el-icon-s-grid',
							title: '人脸融合生成',
							url: '/faces/facesGenerate'
						}, {
							icon: 'el-icon-s-grid',
							title: '人脸融合结果',
							url: '/faces/facesResult'
						}]
					}, {
						icon: 'el-icon-edit',
						title: 'AI生成',
						url: '/ai/ai',
						children: [{
							icon: 'el-icon-tickets',
							title: 'AI拍照',
							url: '/ai/ai'
						}, {
							icon: 'el-icon-picture-outline',
							title: 'AI照片确认',
							url: '/ai/aiConfirm'
						}]
					}]
				},
			};
		},
		methods: {	
		}
	}
</script>
<style lang="scss" scoped>
	.left-tool {
		width: 260px;
		flex-shrink: 0;
		height: 100%;
	}
</style>

效果图

image.png