问题产生
再写项目中需要一个动态侧边栏(带icon),但是官网的使用案例中只有固定的 <icon-star-fill />
<icon-star-fill />
这种方式使用。显然,假设我的项目侧边栏有10个栏目,那么这个固定写法就没有递归写法优雅。
因此我的项目编码中需要自定义icon , 类似于 <icon name='icon-list'>
的方式,之后可以动态的使用改变icon-list 达到动态的icon。
问题解决
幸好 在官网里demo源码中看到了这个写法。
在这个 h 函数 启发了我。那么我就可以写个tsx 使的他能产生动态的 icon dom。
在项目中新建一个 tsx 文件 ,
// 有点丑陋 但是功能在
import { h, compile } from 'vue';
type Props = {
name: string;
};
const icon = (props: Props) => {
return(props.name ? h(compile(`<${props.name}/>`)) : null)
}
export default icon;
那么就可以在递归的项目组件中可以使用了
我的递归组件 menu-tree.vue
<template>
<div v-for="(item, index) in props.data" :key="'menu-item-' + index">
<a-menu-item v-if="!(item.children && item.children.length > 0)" :key="item.routerName">
<icon :name="item.icon" />
<span>{{ item.label }}</span>
</a-menu-item>
<a-sub-menu v-else>
<template #title>
<icon :name="item.icon" />
<span>{{ item.label }}</span>
</template>
<menu-tree :data="item.children" />
</a-sub-menu>
</div>
</template>
<script setup lang="ts">
import { menuType } from '@/types/menu';
import { Icon } from '@arco-design/web-vue';
import { onMounted, h, compile } from 'vue';
// 引入丑陋的 icon.tsx
import icon from './icon';
interface PropType {
data: Array<menuType>;
}
const props = defineProps<PropType>();
</script>
<style lang="less" scoped></style>
项目的侧边栏使用
我传递的数据
最后的效果 (我只有三个加了icon 因此只显示了3个图标)