使用 Vue 3 创建具有任意深度级别的切换递归列表菜单
我们在日常工作中处理大量嵌套数据。一个常见的用例是创建一个 n 级别的切换列表。让我们尝试使用 Vue 3 组合 API 的递归来创建这样一个值列表。 我们将在这条线上创造一些东西。 开始使用 首先,我们可以先定义我们的菜单结构。重要的是,只有当我们可以将菜单中的每个级别都视为相同时,递归才会起作用,这意味着它应该一直具有相同的结构。为此,我们可以决定每个菜单项都有一个标题和一组子项。这些孩子中的
我们在日常工作中处理大量嵌套数据。一个常见的用例是创建一个 n 级别的切换列表。让我们尝试使用 Vue 3 组合 API 的递归来创建这样一个值列表。
我们将在这条线上创造一些东西。
开始使用
首先,我们可以先定义我们的菜单结构。重要的是,只有当我们可以将菜单中的每个级别都视为相同时,递归才会起作用,这意味着它应该一直具有相同的结构。为此,我们可以决定每个菜单项都有一个标题和一组子项。这些孩子中的每一个都将遵循相同的格式,一直向下。
对于这篇文章,我们将使用以下菜单结构:
- Item 1
- Item 1.1
- Item 1.1.1
- Item 1.2
- Item 2
- Item 2.1
让我们创建一个对象数组,如下所示。
const menu = [
{
title: 'Item 1',
children: [
{
title: 'Item 1.1',
children: [
{
title: 'Item 1.1.1',
},
],
},
{
title: 'Item 1.2',
},
],
},
{
title: 'Item 2',
children: [
{
title: 'Item 2.1',
},
],
},
];
# 创建组件
现在让我们创建顶级组件。它将菜单作为道具并将列表显示为 li 元素。
//App.vue
<script setup>
import { ref, defineProps} from 'vue'
import Menu from './Menu.vue'
import {menu} from './menu';
</script>
<template>
<Menu :menu="menu"></Menu>
</template>
//Menu.vue
<script setup>
import { ref } from 'vue'
const props = defineProps({
menu: Array
})
</script>
<template>
<ul>
<template v-for="(item, index) in menu" :key="ite.title">
<li>{{item.title}}</li>
</template>
</ul>
</template>
在 Menu 组件中,我们将遍历菜单数组中的每个项目,并在列表项中显示每个项目的标题。到目前为止所有的 Vue!
嵌套列表
下一个挑战是基于子数组的嵌套列表。
但这里似乎并不难。如果有子数组,我们可以检查是否在列表中创建另一个组件。
<template>
<ul >
<template v-for="(item, index) in menu" :key="index">
<li>{{item.title}}
<Menu v-if="item.children :menu="item.children"></Menu>
</li>
</template>
</ul>
</template>
它应该看起来像这样。
.
欢呼。我们已经创建了一个菜单。 Vue 多么简单。
切换实现
可是等等。如果列表增加,这看起来会很混乱。因此,我们可以尝试创建简单的切换按钮来展开和折叠列表项。
//Menu.vue
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
const expansionState = ref({});
const updateExpansion = (node) => {
expansionState.value[node] = !expansionState.value[node]
}
const props = defineProps({
menu: Array
})
</script>
<template>
<ul >
<template v-for="(item, index) in menu" :key="index">
<li>{{item.title}}
<button v-if="item.children" @click="updateExpansion(item.title)">
{{ expansionState[item.title] ? '-' : '+' }}
</button>
<Menu v-if="item.children && expansionState[item.title]" :menu="item.children"></Menu>
</li>
</template>
</ul>
</template>
令人困惑的是。让我们分解一下。
为了跟踪每个节点的扩展状态,我们创建了一个 expansionState 反应对象。这将在切换按钮的展开和折叠时切换。
当我们开始时,我们的每个 Menu 组件都会将 expandState 设置为 {}。 .如果单击顶层项目 1 旁边的 + 按钮,则扩展状态状态现在将等于 { "Item 1": true }。这将是有状态的 expandState 对象在我们菜单的每个级别上的工作方式!。
我们在这里有最终的简单切换菜单列表。
。
最后的想法
我知道这方面可以有很多改进,但这绝对可以作为一个起点。下一篇文章见。
神速,贾西尔
更多推荐
所有评论(0)