How to dynamically generate the menu component of antd vue

Table of contents

1. Demand background:

2. Solution:

3. Code example:


 

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:

 

Guess you like

Origin blog.csdn.net/valsedefleurs/article/details/130863002