Vue 3 和 <script setup>
的组件,它使用 v-for
来渲染一个嵌套的菜单结构。
[{"id": 1,"title": "Navigator One","children": [{"id": 11, "title": "Item One"},{"id": 12, "title": "Item Two"},{"id": 13, "title": "Item Three"},{"id": 14,"title": "Item Four","children": [{"id": 141, "title": "Sub Item One"}]}]},{"id": 2,"title": "Navigator Two","children": []}
]
Vue 3 组件
<template><el-menu><RecursiveMenu :items="menuData" /></el-menu>
</template><script setup>
import { ref } from 'vue';
import RecursiveMenu from './RecursiveMenu.vue';// 示例数据(通常你会从 API 获取这些数据)
const menuData = ref([// ...(填入上面的 JSON 数据)
]);
</script><!-- RecursiveMenu.vue -->
<template><div v-for="item in items" :key="item.id"><el-sub-menu v-if="item.children && item.children.length" :index="item.id.toString()"><template #title><span>{{ item.title }}</span></template><RecursiveMenu :items="item.children" /></el-sub-menu><el-menu-item v-else :index="item.id.toString()"><span>{{ item.title }}</span></el-menu-item></div>
</template><script setup>
import { defineProps } from 'vue';interface MenuItem {id: number | string; title: string;children?: MenuItem[];
}interface RecursiveMenuProps {items: MenuItem[];
}const props = defineProps<RecursiveMenuProps>();</script>
在这个例子中,RecursiveMenu.vue
是一个递归组件,它负责渲染菜单项和它们的子项。主组件使用 <script setup>
语法,并引入了 RecursiveMenu
组件来渲染整个菜单。菜单数据被存储在一个 ref
中,但通常会从后端 API 获取这些数据。
代码的详细解释:
这段代码是一个 Vue 组件的模板部分,它使用了 Vue 的模板语法来动态渲染一个菜单结构。这个菜单可以是多级的,其中每一级菜单项由 el-sub-menu
和 el-menu-item
组件表示。这里还使用了递归组件 RecursiveMenu
来处理子菜单项。
v-for
指令:v-for="item in items"
:这个指令遍历items
数组,为每个元素创建一个模板实例。每个元素都被赋值给变量item
。:key="item.id"
:这里使用:key
绑定为每个循环的元素提供一个唯一的键值。这是 Vue 推荐的做法,可以提高 DOM 更新的效率。item.id
是每个菜单项的唯一标识符。
- 条件渲染:
v-if="item.children && item.children.length"
:这个指令检查当前菜单项item
是否有子菜单项(即item.children
是否存在且长度大于 0)。如果条件为真,则渲染el-sub-menu
组件;否则,渲染el-menu-item
组件。
el-sub-menu
组件:- 用于表示有子菜单的菜单项。
:index="item.id.toString()"
:设置子菜单的索引,这里将item.id
转换为字符串形式。索引通常用于标识菜单项,以便在需要时可以通过编程方式访问或操作它们。<template #title>
:这是一个具名插槽,用于定义子菜单的标题。在这个插槽内,你可以自定义子菜单标题的显示方式。<span style="font-size: 1.0625rem;">{{ item.title }}</span>
:这里使用了一个<span>
元素来显示菜单项的标题,并通过内联样式设置了字体大小。
<RecursiveMenu :items="item.children" />
:这是一个递归组件的调用,它将当前菜单项的子菜单项作为items
prop 传递给RecursiveMenu
组件。这样,如果子菜单项本身还有子菜单项,它们也会被递归地渲染出来。
el-menu-item
组件:- 用于表示没有子菜单的菜单项。
- 和
el-sub-menu
类似,它也使用:index="item.id.toString()"
来设置索引。 - 菜单项的标题也是通过
<span>
元素显示的,样式和el-sub-menu
中的标题相同。
- 递归组件:
RecursiveMenu
是一个递归组件,它接受一个items
prop,这个 prop 是一个菜单项数组。组件内部使用与上述相同的模板逻辑来渲染这些菜单项。- 递归组件的关键在于它能够调用自身来处理嵌套结构,如多级菜单。
总的来说,这段代码定义了一个能够递归渲染多级菜单结构的 Vue 组件模板。每个菜单项可以是一个包含子菜单项的父菜单项,也可以是一个不包含子菜单项的普通菜单项。通过使用递归组件和条件渲染,这个模板能够灵活地处理任意深度的菜单结构。