vue3-09
菜单图标
安装图标依赖
npm install @ant-design/icons-vue
菜单中使用图标
<template>
<div class="a53">
<a-layout>
<a-layout-header></a-layout-header>
<a-layout>
<a-layout-sider>
<a-menu theme="dark" mode="inline">
<a-menu-item :key="1">
<template #icon>
<highlight-outlined />
</template>
<router-link to="/a3/student">菜单一</router-link>
</a-menu-item>
<a-menu-item :key="2">
<template #icon>
<align-center-outlined />
</template>
<router-link to="/a3/teacher">菜单二</router-link>
</a-menu-item>
<a-menu-item :key="3">
<template #icon>
<strikethrough-outlined />
</template>
菜单3</a-menu-item>
<a-sub-menu :key="4" title="菜单四">
<template #icon>
<sort-descending-outlined />
</template>
<a-menu-item :key="41">菜单41</a-menu-item>
<a-menu-item :key="42">菜单42</a-menu-item>
</a-sub-menu>
</a-menu>
</a-layout-sider>
<a-layout-content>
<router-view></router-view>
</a-layout-content>
</a-layout>
</a-layout>
</div>
</template>
<script setup lang="ts">
import { HighlightOutlined, AlignCenterOutlined, StrikethroughOutlined } from '@ant-design/icons-vue'
</script>
-
图标组件没有全局绑定,需要 import 之后才能使用
-
用
<template #icon></template>
插槽,才能确定图标展示的位置(菜单文字之前)
二次封装图标组件
最终希望用统一的图标组件去使用图标,图标名只是作为一个属性值传递进去,例如:
使用者
<template>
<a-icon icon="highlight-outlined"></a-icon>
<a-icon icon="align-center-outlined"></a-icon>
<a-icon icon="strikethrough-outlined"></a-icon>
<a-icon icon="sort-descending-outlined"></a-icon>
</template>
<script setup lang="ts">
import AIcon from '../components/AIcon1.vue'
</script>
方法1,使用 vue 组件
<script lang="ts" setup>
import {
HighlightOutlined,
AlignCenterOutlined,
StrikethroughOutlined,
SortDescendingOutlined,
} from "@ant-design/icons-vue";
const props = defineProps<{ icon: string }>();
</script>
<template>
<highlight-outlined v-if="icon === 'highlight-outlined'"></highlight-outlined>
<align-center-outlined
v-else-if="icon === 'align-center-outlined'"
></align-center-outlined>
<strikethrough-outlined
v-else-if="icon === 'strikethrough-outlined'"
></strikethrough-outlined>
<sort-descending-outlined
v-else-if="icon === 'sort-descending-outlined'"
></sort-descending-outlined>
</template>
-
缺点:实现太笨
方法2,使用函数式组件
import { h } from "vue";
import * as Icons from "@ant-design/icons-vue";
interface Module {
[p: string]: any;
}
// 参数1: 组件属性
const AIcon = (props: { icon: string }) => {
// console.log(props.icon)
// console.log(Icons)
// 参数1: 组件对象
const im: Module = Icons;
return h(im[toCamelCase(props.icon)]);
};
export default AIcon;
// 将-分隔的单词转换为大驼峰命名的单词
function toCamelCase(str: string) {
// highlight-outlined
return str
.split("-") // ['highlight', 'outlined']
.map((e) => e.charAt(0).toUpperCase() + e.slice(1)) // ['Highlight', 'Outlined']
.join("");
}
/*
Icons 的结构如下
{
HighlightOutlined: HighlightOutlined组件对象,
MonitorOutlined: MonitorOutlined组件对象,
...
}
*/
-
需要动态生成标签的时候,可以考虑使用函数式组件
方法3,使用 jsx 组件
首先,安装
npm install @vitejs/plugin-vue-jsx -D
配置 vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
});
编写一个 Hi.tsx 组件
export default {
props: {
msg: String
},
setup(props: { msg: string }) {
return () => <h5>{props.msg}</h5>
}
}
然后被其它组件使用
<script setup lang="ts">
import Hi from '../components/Hi'
</script>
<template>
<Hi msg="Hello,World"></Hi>
</template>
用 jsx 实现图标组件
import * as Icons from '@ant-design/icons-vue'
interface Module {
[p:string]: any
}
function toCamelCase(str: string) { // highlight-outlined
return str
.split("-") // ['highlight', 'outlined']
.map((e) => e.charAt(0).toUpperCase() + e.slice(1)) // ['Highlight', 'Outlined']
.join(""); // HighlightOutlined
}
export default {
props: {
icon: String
},
setup(props: {icon: string}) {
const im: Module = Icons
const tag = im[toCamelCase(props.icon)] // 图标组件
// HighlightOutlined
return ()=> <tag></tag> // 返回组件标签
}
}