比如我的一个页面有一个位置显示的组件,根据某个值显示不一样的组件,当然可以通过定义一个vue文件,通过一堆if-else显示不一样的组件,但是这样不够灵活,而且很麻烦,那么这里我们就可以通过jsx实现通过ts代码返回不一样的组件
以封装icon图标组件为例,我引入了ant-design-vue的库,如果我们平时用的话,可能要像下边这样
<template>
<div>
<a-layout>
<a-layout-header :style="headerStyle">Header</a-layout-header>
<a-layout>
<a-layout-sider>
<a-menu theme="dark">
<a-menu-item :key="2">
<HddOutlined />
菜单二</a-menu-item>
</a-menu>
</a-layout-sider>
<a-layout-content :style="contentStyle">
<RouterView></RouterView>
</a-layout-content>
</a-layout>
</a-layout>
</div>
</template>
<script setup lang="ts" name="News">
import {CopyOutlined,HddOutlined} from '@ant-design/icons-vue'
</scirpt>
那这样的话就很麻烦,我每次在一个地方使用都要引入对应的icon才可以使用,那么我们可可不可以自己封装一个组件,通过传入不同的名字,显示不一样的组件,见如下语法
import * as icons from '@ant-design/icons-vue'
interface Module{
[p:string]:any
}
export default {
//还需要在这定义标签属性的每个值得类型,注释:类型需要为大写
props:{
msg:String
},
//这就是标签传过来的值,是一个对象
setup(props:{msg:string}){
const im:Module=icons
//标签名称
let name =im[props.msg];
return ()=>(<>
<name></name>
</>)
}
}
使用如下:
<template>
<div>
<a-layout>
<a-layout-header :style="headerStyle">Header</a-layout-header>
<a-layout>
<a-layout-sider>
<a-menu theme="dark">
<a-menu-item :key="1">
<template #icon>
//如果自定义的标签只返回一个标签,可以不加,但是如果是一堆标签的话,需要在外层加一个div,否则会出现一个警告(Extraneous non-props attributes (class) were passed to component but could not be automatica)
<div>
//这里就是自定义的标签组件
<Aicon msg="SettingOutlined"/>
</div>
</template>
菜单一</a-menu-item>
</a-layout-sider>
<a-layout-content :style="contentStyle">
<RouterView></RouterView>
</a-layout-content>
</a-layout>
</a-layout>
</div>
</template>
<script setup lang="ts" name="News">
import Aicon from '@/components/Aicon'
</script>