Table of contents
1. Demand background:
The vertical menu component needs to be dynamically generated, and the first-level menu of the data source may or may not contain the second-level submenu. The difficulty lies in whether the sub-menu is included or not determines whether to generate the <a-menu-item> component or the <a-sub-menu> component, which brings difficulty to the development. And v-if, v-else and other conditional judgments in the template preview of vue cannot appear on the same level label as the v-for loop.
2. Solution:
Make good use of the template tag, put the v-for loop in the template tag, and then use the v-if, v-else statement to determine whether it contains a submenu, and decide whether to generate <a-menu-item> or <a-sub-menu>
3. Code example:
template template
<a-menu
:default-selected-keys="['1']"
:open-keys="openKeys"
mode="inline"
:selected-keys="[current]"
@click="handleClick"
@openChange="onOpenChange"
>
<template v-for="item in menus">
<a-menu-item v-if="!item.children" :key="item.key">
<a-icon style="margin-right: 8px; font-size: 12px" :type="item['icon-type']" />
<span style="font-weight: 500; font-size: 14px">{
{ item.label }}</span>
</a-menu-item>
<a-sub-menu v-else :key="item.key">
<div slot="title">
<ops-icon style="margin-right: 8px; font-size: 12px" :type="item['icon-type']" /><span
style="font-weight: 500; font-size: 14px"
>{
{ item.label }}</span
>
</div>
<a-menu-item v-for="childItem in item.children" :key="childItem.key">
<a-icon style="margin-right: 8px; font-size: 12px" :type="childItem['icon-type']" />
<span style="font-weight: 500; font-size: 14px">{
{ childItem.label }}</span>
</a-menu-item>
</a-sub-menu>
</template>
js code
data() {
return {
collapsed: false,
current: '1',
rootSubmenuKeys: ['sub1', 'sub2'],
openKeys: ['sub1'],
menus: [
{
key: '1',
'icon-type': 'zhujiqiang',
label: '一级菜单 1',
},
{
key: '2',
'icon-type': 'zhujijiankong',
label: '一级菜单 2',
},
{
key: '3',
'icon-type': 'wangluotuobu',
label: '一级菜单 3',
},
{
key: '4',
'icon-type': 'wodekanban',
label: '一级菜单 4',
},
{
key: 'sub1',
'icon-type': 'wangyexingneng',
label: '一级菜单 5',
children: [
{
key: '5',
'icon-type': 'gailan',
label: '二级菜单 5-1',
},
{
key: '6',
'icon-type': 'xingnengpinggu',
label: '二级菜单 5-2',
},
{
key: '7',
'icon-type': 'yuansuxingneng',
label: '二级菜单 5-3',
},
],
},
{
key: 'sub2',
'icon-type': 'wangzhanjiankong',
label: '二级菜单 6',
children: [
{
key: '8',
'icon-type': 'zonglan',
label: '二级菜单 6-1',
},
{
key: '9',
'icon-type': 'shishizhuangtai',
label: '二级菜单 6-1',
},
{
key: '10',
'icon-type': 'tongji',
label: '二级菜单 6-1',
},
],
},
],
}
methods: {
toggleCollapsed() {
this.collapsed = !this.collapsed
},
handleClick(e) {
console.log('click ', e)
this.current = e.key
},
onOpenChange(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] : []
}
},
},
The final effect is as follows: