最近项目需要,有需要动态创建下拉菜单的需求,特此记录一下。

vue版本:3.1.4

ant-design-vue版本:2.1.6

需求是下拉菜单项可以根据配置来控制是否显示,那么就需要用到 v-for 和 v-if 的结合。

v-for 和 v-if 是不能同时应用到元素上面的,所以需要用 template 来承载 v-for,代码如下:

<a-dropdown v-if="moreButtons.length > 0">
  <a-button type="primary" @click.prevent>…</a-button>
  <template #overlay>
    <a-menu @click="dropdownMenuItemClick">
      <template v-for="controlItem in moreButtons">
        <a-menu-item v-if="controlItem.show" :key="controlItem.name">
          {{ controlItem.text }}
        </a-menu-item>
      </template>
    </a-menu>
  </template>
</a-dropdown>

下面的写法也是可以的,v-if 也放到一个单独的template中

<a-dropdown v-if="moreButtons.length > 0">
  <a-button type="primary" @click.prevent>…</a-button>
  <template v-for="controlItem in moreButtons">
    <template v-if="controlItem.show">
      <a-menu-item :key="controlItem.name">{{ controlItem.text }}</a-menu-item>
    </template>
  </template>
</a-dropdown>

需要注意的一点,如果是结合 v-if 判断的话,key 一定要绑定在 a-menu-item 元素上!!!

如下面的代码,虽然可以正常动态显示菜单,但是在点击菜单项项的时候,拿到的 key 都是0。

<a-dropdown v-if="moreButtons.length > 0">
  <a-button type="primary" @click.prevent>…</a-button>
  <template #overlay>
    <a-menu @click="dropdownMenuItemClick">
      <template v-for="controlItem in moreButtons" :key="controlItem.name">
           <a-menu-item v-if="controlItem.show">{{ controlItem.text }}</a-menu-item>
      </template>
    </a-menu>
  </template>
</a-dropdown>

分别点了“按钮1”和“按钮3”,输出的key都是0

 正常应该是点击哪一个按钮,就输出哪一个按钮的key。

如下:

点击“按钮1”,输出的key是 “button1”

点击“按钮3”,输出的key是 “button3”

如果不需要结合 v-if 判断的话,key可以绑定在template上;或者直接去掉template,在a-menu-item上直接 v-for

部分代码如下:

<a-dropdown
  v-if="contextMenuItems.length > 0 || moreContextMenuItems.length > 0"
  :trigger="['contextmenu']"
>
  <template #overlay>
    <a-menu @click="contextMenuItemClick">
      <!--在a-menu-item上 v-for 及 key 绑定-->
      <a-menu-item v-for="menuItem in contextMenuItems" :key="menuItem.name">
        {{ menuItem.text }}
      </a-menu-item>
      <a-sub-menu v-if="moreContextMenuItems.length > 0" key="moreMenus" title="更多...">
      <!--在 template 上 v-for 及 key 绑定-->
        <template v-for="menuItem in moreContextMenuItems" :key="menuItem.name">
          <a-menu-item>{{ menuItem.text }}</a-menu-item>
        </template>
      </a-sub-menu>
    </a-menu>
  </template>
</a-dropdown>

完整代码如下:

<script setup>
import { ref } from 'vue';
const moreButtons = ref([
{
  name: 'button1',
  text: '按钮1',
  show: true,
},
{
  name: 'button2',
  text: '按钮2',
  show: false,
},
{
  name: 'button3',
  text: '按钮3',
  show: true,
},
]);

/**下拉按钮点击事件 */
const dropdownMenuItemClick = (e) => {
  console.log(e);
  //clickEvent(e.key);
};
</script>

<template>
  <a-dropdown v-if="moreButtons.length > 0">
    <a-button type="primary" @click.prevent>…</a-button>
    <template v-for="controlItem in moreButtons">
      <a-menu-item v-if="controlItem.show" :key="controlItem.name">
      {{ controlItem.text }}
      </a-menu-item>
    </template>
  </a-dropdown>
</template>

Logo

前往低代码交流专区

更多推荐