<template> <v-list> <div v-for="route in propsRoutes" :key="route.path"> <!-- group绑定当前路由实现List的自动展开 --> <!-- 若当前路由对象存在children属性则渲染 <v-list-group>(存在子路由),否则渲染 <v-list-item> --> <v-list-group v-if="hasRouteChildren(route)" :group="route.path" :class="isLevelOneRoute(route) ? '' : 'ml-5'" > <template #activator> <v-list-item-icon v-if="route.meta.icon"> <v-icon>{{ `mdi-${route.meta.icon}` }}</v-icon> </v-list-item-icon> <v-list-item-title>{{ route.meta.title }}</v-list-item-title> </template> <!-- 递归组件 --> <nested-list :props-routes="route.children" /> </v-list-group> <!-- :to="{ name: route.name }" 基于命名路由的路由跳转 --> <div v-else> <v-list-item :to="routeNameTo(route)" :class="isLevelOneRoute(route) ? '' : 'ml-5'" :color="activeColor" > <v-list-item-icon v-if="listItemConfig(route, 'icon')"> <v-icon>{{ `mdi-${listItemConfig(route, "icon")}` }}</v-icon> </v-list-item-icon> <v-list-item-title v-if="listItemConfig(route, 'title')"> {{ listItemConfig(route, "title") }} </v-list-item-title> </v-list-item> </div> </div> </v-list> </template> <script> export default { name: 'NestedList', props: { propsRoutes: { type: Array, required: true, default() { return [] } }, activeColor: { type: String, default: 'success' } }, methods: { /** * 判断当前路径对象是否为路由表的一级路由 * @param route 当前路径对象 * @returns {boolean} */ isLevelOneRoute(route) { return this.propsRoutes.includes(route) }, /** * 判断当前路径对象是否被渲染为 list-group * @param route * @returns {boolean|boolean} */ hasRouteChildren(route) { // 在根据角色筛选路由时,若原本有两个子路由,筛选后剩余一个,可保证父路由渲染为分组 if (route.meta && route.meta.isGroup) { return true } return route.children && route.children.length > 1 }, /** * 根据当前路径对象是否含有children属性,来配置 list-item 的文本及图标 * @param route * @param property * @returns {string} */ listItemConfig(route, property) { return route.children ? route.children[0]['meta'][property] : route.meta[property] }, /** * list-item 基于命名路由的路由跳转 * @param route * @returns {{name: (*)}} 含有name属性的路径对象 */ routeNameTo(route) { return { name: route.children ? route.children[0].name : route.name } } } } </script>