问题描述
在练习vue3路由的时候,发现如果添加路由,创造新的路由页面非常麻烦,每次都要在配置新的路由之后,需要手动添加新的菜单导航。
想要实现只要添加路由创建页面,就能自动渲染出菜单的方式。
- 未改变前的路由配置
- 静态的路由渲染
下面这张图中的代码,通常都要在添加路由之后,重新加一条 router-link 比较繁琐。想要省略这个步骤,静默渲染页面。
期望效果
自动渲染路由菜单
在每次添加路由之后,省略router-link步骤,自动渲染新增路由对应菜单。
具体实现
步骤分析
-
获取到已配置路由
可以根据useRouter().getRoutes()
获取所有配置的路由 -
根据路由列表,筛选出符合条件的路由
在路由文件route/index.ts
中配置meta
,通过fileter
或者是循环遍历
筛选出所有顶级路由(不包含子路由) -
渲染路由页面
结合 element-plus组件样式,和 router-link 遍历实现
步骤实施
- 配置路由
在原来路由配置的基础上添加meta
- 获取路由
getRoutes()
会获取到所有的路由和路由配置,包含children中的也会被铺开,全部展示
import { useRouter } from 'vue-router';
const router = useRouter();
const routes = router.getRoutes();
打印输出的效果包含所有的路由信息。
- 筛选路由
我想要的是一级路由,不包含children中的数据
const router = useRouter();
const cRoutr: Array<RouteRecordRaw> = [];
//记录所有子路由
router.getRoutes().forEach(route => {
if (route.children.length > 0) {
cRoutr.push(...route.children)
}
});
//筛选出不包含子路由的路由
const routers = computed(() => {
return router.getRoutes()
.filter(item => {
return !cRoutr.find(i => i.name === item.name)
})
.sort((a, b) => (a.meta.navOrder as number) - (b.meta.navOrder as number))//正序排序
});
console.log('路由', routers.value)
输出效果:
就是我想要的一级路由
- 渲染页面
结合element-plus的menu组件
Menu菜单组件
<el-menu active-text-color="rgba(163, 104, 218, 0.785)" background-color="#545c64" class="el-menu-vertical-demo"
default-active="0" text-color="#fff">
<router-link v-for="route in routers" :key="route.name" :to="route.path" :default-active="0">
<el-menu-item :index="route.meta.navOrder?.toString()">
<span>{{ route.meta.title }}</span>
</el-menu-item>
</router-link>
</el-menu>
最终实现代码
<el-menu active-text-color="rgba(163, 104, 218, 0.785)" background-color="#545c64" class="el-menu-vertical-demo"
default-active="0" text-color="#fff">
<router-link v-for="route in routers" :key="route.name" :to="route.path" :default-active="0">
<el-menu-item :index="route.meta.navOrder?.toString()">
<span>{{ route.meta.title }}</span>
</el-menu-item>
</router-link>
</el-menu>
const router = useRouter();
const cRoutr: Array<RouteRecordRaw> = [];
router.getRoutes().forEach(route => {
if (route.children.length > 0) {
cRoutr.push(...route.children)
}
});
const routers = computed(() => {
return router.getRoutes()
.filter(item => {
return !cRoutr.find(i => i.name === item.name)
})
.sort((a, b) => (a.meta.navOrder as number) - (b.meta.navOrder as number))//正序排序
});
这样,在每次添加路由页面的时候,只需要创建页面,配置路由和路由meta。就可以自动渲染新增页面了。