vue.js - Vuetify 3 v-list-group - 打开组时折叠其他子菜单

标签 vue.js vuetify.js vuetifyjs3

我正在使用 Vuetify 3,并尝试使用 v-list-group 组件在 Vuetify 抽屉导航内实现可折叠垂直菜单。当单击另一个菜单项展开时( Accordion 行为),我需要当前展开的菜单项折叠。我已经创建了菜单列表,但 Accordion 效果没有按预期工作。

模板:

<v-navigation-drawer
        v-model="drawer"
        temporary
        location="right"
        theme="dark"
    >
        <v-list density="compact">
            <v-list-group v-model="item.active" v-for="item in menuItems">
                <template v-slot:activator="{ props }">
                    <v-list-item
                        :key="item.title"
                        v-bind="props"
                        :title="item.title"
                    ></v-list-item>
                </template>

                <v-list-item
                    v-for="subMenu in item.subMenuItems"
                    :key="subMenu"
                    :title="subMenu"
                ></v-list-item>
            </v-list-group>
        </v-list>
    </v-navigation-drawer>

脚本:

<script setup>

const menuItems = ref([
    {
        title: "Menu Item 1",
        active: false,
        subMenuItems: ["Sub Menu Item 1", "Sub Menu Item 2", "Sub Menu Item 3"]
    },
    {
        title: "Menu Item 2",
        active: false,
        subMenuItems: ["Sub Menu Item 1", "Sub Menu Item 2", "Sub Menu Item 3"]
    },
    {
        title: "Menu Item 3",
        active: false,
        subMenuItems: ["Sub Menu Item 1", "Sub Menu Item 2", "Sub Menu Item 3"]
    }
])

</script>

在 Vuetify 2 中,我可以为 v-list-group 组件的 v-model 分配一个变量,但这不适用于 Vuetify 3(更改值不会改变折叠/展开状态)。

v-list-group 组件不包含用于手动修改其状态的 is-open 属性(有一个 isOpen 标志它被传递到激活器插槽,但它是只读的)。

最佳答案

是的,看起来已经改变了,您现在需要使用周围的v-list来完成它。

v-list:opened 属性是一个数组,对应于打开的组。将哪些值放入列表中由 v-list-group:value 属性确定。要最多打开一个组,您可以监听 @update:opened 事件并相应地修复列表。

因此,使用 ref opened = ref([]),您可以执行以下操作:

<v-list
  :opened="opened"
  @update:opened="newOpened => opened = newOpened.slice(-1)"
>
  <v-list-group
    v-for="item in menuItems"
    :key="item.title"
    :value="item"
  >
  ...

使用@update:opened="opened = $event.slice(-1)",更新列表时,除了最后一个元素之外的所有元素都将被删除。这将关闭除最后单击的组之外的所有组。

:value="item" 确定将放入 opened 数组中的内容。它是什么并不重要,只要它对于每个组来说都是唯一的(除非您希望项目一起打开和关闭,那么它们应该具有相同的值)。

这是一个片段:

const {
  createApp,
  ref,
  computed
} = Vue;
const {
  createVuetify
} = Vuetify
const vuetify = createVuetify()
createApp({
  setup() {
    const menuItems = ref([{
        title: "Menu Item 1",
        active: false,
        subMenuItems: ["Sub Menu Item 1", "Sub Menu Item 2", "Sub Menu Item 3"]
      },
      {
        title: "Menu Item 2",
        active: true,
        subMenuItems: ["Sub Menu Item 1", "Sub Menu Item 2", "Sub Menu Item 3"]
      },
      {
        title: "Menu Item 3",
        active: false,
        subMenuItems: ["Sub Menu Item 1", "Sub Menu Item 2", "Sub Menu Item 3"]
      }
    ])
    const opened = ref([])

    return {
      opened,
      drawer: ref(true),
      menuItems,
    }
  }
}).use(vuetify).mount('#app')
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d7a1a2b2a3beb1ae97e4f9e6f9ee" rel="noreferrer noopener nofollow">[email protected]</a>/dist/vuetify.min.css" />
<link href="https://cdn.jsdelivr.net/npm/@mdi/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5d3b3233291d687325" rel="noreferrer noopener nofollow">[email protected]</a>/css/materialdesignicons.min.css" rel="stylesheet">
<div id="app" class="d-flex justify-center">
  <v-app>
    <v-card>
      <v-layout>

        <v-navigation-drawer v-model="drawer" temporary>
          <v-list density="compact" :opened="opened" @update:opened="opened = $event.slice(-1)">
            <v-list-group v-for="item in menuItems" :key="item.title" :value="item">
              <template v-slot:activator="{props, isOpen}">
                    <v-list-item
                        v-bind="props"
                        :key="item.title" 
                        :title="item.title"
                    ></v-list-item>
                </template>

              <v-list-item v-for="subMenu in item.subMenuItems" :key="subMenu" :title="subMenu"></v-list-item>
            </v-list-group>
          </v-list>
        </v-navigation-drawer>

        <v-main style="height: 500px;">

        </v-main>
      </v-layout>
    </v-card>
  </v-app>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4f393a2a3b2629360f7c617e6176" rel="noreferrer noopener nofollow">[email protected]</a>/dist/vuetify.min.js"></script>

关于vue.js - Vuetify 3 v-list-group - 打开组时折叠其他子菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75743318/

相关文章:

vue.js - Vue 3-Vuetify 3 : color--text not working

javascript - vue.js 中的计数器不增加

vue.js - 什么时候在 vue 中使用 created() 方法?

vuejs2 - Vuetify v-data-table 将列拖到一起并调整大小

ajax - 如何为每个事件加载新的外部 HTML?

vue.js - 获取 vuetify 列表的选择

javascript - vue js Prop 重置计时器

javascript - 缩略图网格显示在列中

vue.js - 重置 Vuetify 表单验证

css - 如何让 v-col 变成可滚动的?