ant-design-vue導航菜單a-menu的使用解讀
此文章包含了遞歸生成三級菜單,刷新狀態(tài)保留,只展開一個父級菜單等常見問題。
一、效果
可以看到遞歸生成三級菜單,刷新狀態(tài)保留,只展開一個父級菜單等常見問題得以解決。我自己的電腦設備老舊,反應緩慢的問題請忽略。

二、關鍵的API
說實話遇到問題了不知道該怎么解決,說白了還是不懂得API的使用,對相關的API不夠了解,熟悉了API怎么操作都行。下面說說用到但是又容易混淆的API。
1.defaultSelectedKeys 默認選中的key
這里的key對應的是a-menu-item上面綁定的key,如果被選中,會進行導航的跳轉以及被給予高亮狀態(tài)。
2.openKeys 展開的a-sub-menu的key
這里的key對應的是a-sub-menu上面綁定的key。如果綁定在a-menu上,對應的子菜單會打開。
3.selectedKeys 受控選中的key
這里的key對應的是a-menu-item上面綁定的key,如果被選中,會進行導航的跳轉以及被給予高亮狀態(tài)。
與defaultSelectedKeys 有什么區(qū)別:
- 這兩個屬性為二選一使用,如果同時使用時,defaultSelectedKeys無效,將會以selectedKeys為準。
- 如果你只是希望指定一個初始化選中的菜單項,請使用defaultSelectedKeys;
- 如果你需要每次通過傳入不同的props改變Menu組件的選中項,請使用selectedKeys。
三、注意事項
此處強調一點,如果是一級以及二級菜單的生成,普通的兩層for循環(huán)結合遞歸以及v-if生成即可。
如果是想使用a-menu生成三級或者三級以上的菜單,那么就需要定義在單文件內定義函數式組件。那為什么不推薦單文件的形式定義組件,而是使用函數式組件?
以下是官方文檔的說明:

四、代碼
<template>
<a-layout id="components-layout-demo-custom-trigger" style="height:100%">
<a-layout-sider theme="light" v-model="collapsed" :trigger="null" collapsible>
<div >
<a-menu
:inlineIndent="inlineIndent"
:defaultSelectedKeys="[$route.path]"
:openKeys="openKeys"
mode="inline"
:inline-collapsed="collapsed"
@openChange="onOpenChange"
@click="menuClick">
<!-- 菜單遍歷的開始 -->
<template v-for="item in list">
<!-- 如果當前遍歷項沒有children,視為子菜單項,注意所有的key都是path用于路由跳轉,以及當前選中記錄 -->
<a-menu-item v-if="!item.children" :key="item.path">
<i :class="item.icon" />
<span>{{ item.title }}</span>
</a-menu-item>
<!-- 否則視為子菜單,傳入菜單信息并且運用下面定義的函數式組件 -->
<sub-menu v-else :key="item.path" :menu-info="item" />
</template>
</a-menu>
</div>
</a-layout-sider>
<a-layout>
<a-layout-content :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }">
<router-view/>
</a-layout-content>
</a-layout>
</a-layout>
</template>
<script>
import { Menu } from 'ant-design-vue';
// 定義函數式組件
const SubMenu = {
template: `
<a-sub-menu :key="menuInfo.path" v-bind="$props" v-on="$listeners">
<span slot="title">
<i :class="menuInfo.icon" /><span>{{ menuInfo.title }}</span>
</span>
<template v-for="item in menuInfo.children">
<a-menu-item v-if="!item.children" :key="item.path">
<i :class="item.icon" />
<span>{{ item.title }}</span>
</a-menu-item>
<sub-menu v-else :key="item.path" :menu-info="item" />
</template>
</a-sub-menu>
`,
name: 'SubMenu',
// must add isSubMenu: true 此項必須被定義
isSubMenu: true,
props: {
// 解構a-sub-menu的屬性,也就是文章開頭提到的為什么使用函數式組件
...Menu.SubMenu.props,
// 接收父級傳遞過來的菜單信息
menuInfo: {
type: Object,
default: () => ({}),
},
},
};
export default {
data() {
return {
// 菜單縮進
inlineIndent:12,
// 默認不折疊
collapsed: false,
// 全部頂級父節(jié)點,用來控制所有父級菜單只展開其中的一項,可用遍歷菜單信息進行賦值
rootSubmenuKeys: ['/infomationManage','/safeInfoManage','/qualityInfoManage'],
// 展開的父菜單項
openKeys: [],
// 選中的子菜單項
defaultSelectedKeys: [this.$route.path],
// 菜單信息,可從后臺獲取
list: [
{
key: '1',
title: '項目信息管理',
path: '/infomationManage',
icon:'iconfont icon-information'
},
{
key: '2',
title: '安全信息管理',
path: '/safeInfoManage',
icon:'iconfont icon-anquan',
children: [
{
key: '2.1',
title: '安全風險管理',
path: '/safeRisk',
icon:'',
children: [
{
key: '2.1.1',
title: '風險分類管理',
path: '/riskClassifyManage',
icon:'',
},
{
key: '2.1.2',
title: '分類辨識',
path: '/classifyIdentity',
icon:'',
}
],
},
],
},
{
key: '3',
title: '質量信息管理',
path: '/qualityInfoManage',
icon:'iconfont icon-zhiliang',
children:[
{
key: '3.1',
title: '質量控制點管理',
path: '/controlPointManage',
icon:'',
}
]
}
],
}
},
created(){
// 將從緩存中取出openKeys
const openKeys = window.sessionStorage.getItem('openKeys')
if(openKeys){
// 存在即賦值
this.openKeys = JSON.parse(openKeys)
}
},
methods: {
// 點擊菜單,路由跳轉,注意的是當點擊MenuItem才會觸發(fā)此函數
menuClick({ item, key, keyPath }) {
// 獲取到當前的key,并且跳轉
this.$router.push({
path: key
})
},
onOpenChange(openKeys) {
// 將當前打開的父級菜單存入緩存中
window.sessionStorage.setItem('openKeys', JSON.stringify(openKeys))
// 控制只打開一個
const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1);
if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
this.openKeys = openKeys;
} else {
this.openKeys = latestOpenKey ? [latestOpenKey] : [];
}
},
},
// 注冊局部組件
components: {
'sub-menu': SubMenu,
},
};
</script>
<style>
</style>
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vue框架和react框架的區(qū)別以及各自的應用場景使用
這篇文章主要介紹了vue框架和react框架的區(qū)別以及各自的應用場景使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
vue3中vite.config.js相關常用配置超詳細講解
在Vue3項目中vite.config.js文件是Vite構建工具的配置文件,它用于定義項目的構建和開發(fā)選項,這篇文章主要介紹了vue3中vite.config.js相關常用配置的相關資料,需要的朋友可以參考下2025-04-04

