如何动态生成antd vue的menu组件

目录

1. 需求背景:

2. 解决方案:

3. 代码示例:


1. 需求背景:

需要根据动态生成垂直菜单组件,数据来源的一级菜单可能包含二级子菜单,也可能不包含二级子菜单。难度在于是否包含二级子菜单决定着生成<a-menu-item>组件还是<a-sub-menu>组件,因此给开发带来难度。且vue的模板预览中v-if, v-else等条件判断不能与v-for循环出现在同级标签上。

2. 解决方案:

善用template标签,将v-for循环放在template标签,再将v-if, v-else语句判断是否包含子菜单,决定生成<a-menu-item>还是<a-sub-menu>

3. 代码示例:

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代码

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] : []
      }
    },
  },

最终实现效果如下:

猜你喜欢

转载自blog.csdn.net/valsedefleurs/article/details/130863002
今日推荐