antd 中左侧菜单栏icon图标自定义

文章介绍了如何在Vue项目中封装SVG图标为组件,首先展示了组件`src/components/svgIcon/index.vue`的代码,该组件使用`img`标签展示图标。然后在`main.ts`中全局引入并注册这个SVGIcon组件。最后,给出了在路由`router/index.ts`中如何使用这个自定义图标的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

左侧菜单栏中的图标名称其实是一个图标的组件,要自定义图标,就要将图标封装成一个组件,然后使用。

封装组件

src/components/svgIcon/index.vue

<template>
  <div>
    <img src="@/assets/tuceng.png" alt="" />
  </div>
</template>

<script setup></script>

<style lang="less" scoped>
img {
  width: 20px;
  height: 20px;
}
</style>

全局引入注册

main.ts

import svgIcon from '@/components/svgIcon/index.vue';

app.component('svgIcon',svgIcon);

使用

router/index.ts

 {
        name: 'xxxx',
        path: '/xxxx',
        meta: { icon: 'svgIcon', title: '标题' },
}

 

<think>好的,用户想了解如何使用antd-vue开发菜单栏、面包屑和Tab栏的功能。首先,我需要回忆一下antd-vue的相关组件和API。菜单栏通常使用a-menu组件,面包屑用a-breadcrumb,Tab栏可能是a-tabs或者自定义的组件组合。 接下来,我需要结合用户提供的引用内容。用户提到引用4中的路由标签页和面包屑自动根据路由变化,这涉及到路由监听。在vue3中,使用vue-router-next,可能需要用useRoute和useRouter来获取当前路由信息,并动态更新菜单和面包屑。 用户的问题还涉及到点击面包屑导航时左侧菜单栏没有实时更新的问题,如引用1所述。这可能是因为菜单栏的状态没有随着路由变化而更新,需要监听路由变化并手动触发状态更新。比如,在菜单组件中监听路由路径,动态设置selectedKeys和openKeys。 关于Tab栏,引用4中的例子展示了如何通过关闭标签页跳转到前一个路由,并更新标签数组。这需要维护一个标签列表,每个标签对应一个路由,当路由变化时添加或激活对应的标签。同时,关闭标签时需要处理路由跳转和数组更新。 另外,用户提到引用3中的a-select的getPopupContainer属性,这可能与组件层级和定位有关,但暂时和菜单、面包屑关系不大,不过需要注意组件可能的层级问题,比如下拉菜单的位置是否正确,可能需要调整父容器。 需要给出具体的代码示例,比如配置路由信息,使用a-menu生成菜单,结合vue-router的router-link或编程式导航。面包屑部分可能需要根据路由的meta信息生成层级结构,或者根据当前路由的路径动态生成。Tab栏则需要结合路由的变化,动态添加或切换标签,并支持关闭功能。 还需要考虑响应式设计,适配不同设备,如引用2提到的模板。可能需要使用媒体查询或antd-vue的响应式布局组件。 最后,要确保代码符合vue3的Composition API写法,使用setup函数和响应式API如ref、reactive,以及生命周期钩子来监听路由变化。 总结步骤:配置路由结构,创建菜单组件并绑定路由,实现面包屑动态生成,管理Tab栏状态与路由同步,处理菜单和标签的交互逻辑,如点击菜单更新路由和标签,关闭标签时路由跳转等。</think>### 使用 antd-vue 开发菜单栏、面包屑和 Tab 栏的示例教程 #### 一、菜单栏实现 1. **配置路由信息** 在 `router.ts` 中定义带 `meta` 属性的路由结构,用于存储菜单标题、图标等信息: ```typescript const routes = [ { path: '/dashboard', name: 'Dashboard', component: () => import('@/views/Dashboard.vue'), meta: { title: '仪表盘', icon: 'dashboard' } }, { path: '/user', name: 'User', component: () => import('@/views/User.vue'), meta: { title: '用户管理', icon: 'user' } } ]; ``` 2. **动态生成菜单** 使用 `a-menu` 组件绑定路由数据,通过 `v-for` 渲染菜单项,并监听路由变化更新选中状态: ```vue <template> <a-menu v-model:selectedKeys="selectedKeys" mode="inline" @click="handleMenuClick" > <template v-for="route in menuRoutes" :key="route.path"> <a-menu-item :key="route.path"> <template #icon> <icon-font :type="route.meta.icon" /> </template> {{ route.meta.title }} </a-menu-item> </template> </a-menu> </template> <script setup> import { ref, watch } from 'vue'; import { useRouter, useRoute } from 'vue-router'; const router = useRouter(); const route = useRoute(); const selectedKeys = ref([route.path]); // 监听路由变化更新选中状态 watch(() => route.path, (newPath) => { selectedKeys.value = [newPath]; }); </script> ``` #### 二、面包屑实现 通过 `a-breadcrumb` 结合路由 `matched` 属性动态生成层级: ```vue <template> <a-breadcrumb> <a-breadcrumb-item v-for="(item, index) in breadcrumbItems" :key="index"> {{ item.meta.title }} </a-breadcrumb-item> </a-breadcrumb> </template> <script setup> import { computed } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); const breadcrumbItems = computed(() => route.matched.filter(r => r.meta?.title) ); </script> ``` #### 三、Tab 栏实现 1. **状态管理** 使用 `pinia` 或 `reactive` 存储标签页状态: ```typescript import { reactive } from 'vue'; interface TabItem { path: string; title: string; } const tabStore = reactive({ tabs: [] as TabItem[], activeKey: '' }); ``` 2. **标签页组件** 监听路由变化动态添加/激活标签,实现关闭逻辑: ```vue <template> <a-tabs v-model:activeKey="tabStore.activeKey" type="editable-card" @edit="handleTabClose" > <a-tab-pane v-for="tab in tabStore.tabs" :key="tab.path" :tab="tab.title" :closable="tabStore.tabs.length > 1" > <router-view /> </a-tab-pane> </a-tabs> </template> <script setup> import { watch } from 'vue'; import { useRoute, useRouter } from 'vue-router'; const route = useRoute(); const router = useRouter(); // 路由变化时更新标签 watch(() => route.fullPath, (newPath) => { const exists = tabStore.tabs.some(tab => tab.path === newPath); if (!exists) { tabStore.tabs.push({ path: newPath, title: route.meta.title }); } tabStore.activeKey = newPath; }); // 处理标签关闭 const handleTabClose = (targetKey) => { const index = tabStore.tabs.findIndex(tab => tab.path === targetKey); if (index !== -1) { tabStore.tabs.splice(index, 1); // 跳转到前一个标签 if (targetKey === route.path) { const prevTab = tabStore.tabs[index - 1]; router.push(prevTab.path); } } }; </script> ``` #### 四、联动优化 - **菜单与路由同步**:通过 `router.push()` 实现菜单点击跳转[^4] - **层级问题处理**:若组件显示异常,可通过调整 `getPopupContainer` 属性修复[^3] - **状态持久化**:使用 `localStorage` 存储标签页状态实现页面刷新恢复
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值