vuerouter 4.0 + vue3 + vuex 实现动态路由
之前自学过vue-router,但都是停留在静态路由的层面,对于动态路由的实现一窍不通,刚好公司让维护一个使用了动态路由的项目,所以参照项目和网上的信息自己实现了一下,做个记录。使用vuecli4.5创建的小项目,单纯实现动态路由,感兴趣可以戳https://github.com/shenxuekai/asyncrouter.git,或者git clone,说下项目配置:vue3 + ts + v
之前自学过vue-router,但都是停留在静态路由的层面,对于动态路由的实现一窍不通,刚好公司让维护一个使用了动态路由的项目,所以参照项目和网上的信息自己实现了一下,做个记录。
使用vuecli4.5创建的小项目,单纯实现动态路由,感兴趣可以戳https://github.com/shenxuekai/asyncrouter.git,或者git clone,说下项目配置:vue3 + ts + vue-router4.0 + vuex,4.0目前(2021-12-7)还是beta版本,比较适合vue3。至于vue2,最好搭配router3.x,网上有很多实现的例子,可以自行百度。
目前动态路由实现主要有两种方式:
1.前端定义好所有路由,登录时向后端请求权限码或者识别码,然后根据和后端约定好的方式对路由过滤,最后把过滤后的结果设置给router
2.前端只定义组件和界面,以及少部分路由,在登陆时像后端传递用户名/角色 后端返回该角色/用户对应的所有路由,前端接收到结果不需要再次过滤,稍微处理后就能使用
这里的实现方式类似第一种的简化版
先说下思路,首先构造一个静态路由,其次在登录界面 用户登录时对用户身份进行校验,如果满足某些条件则新增路由,最后将路由展示在home界面
目录结构:
1.构造静态路由:根据公共路由配置router并导出
import {createRouter, createWebHistory, RouteRecordRaw} from 'vue-router'
import baseRoutes from "@/router/baseRoutes";//格式同routes
import {asyncRoutes} from "@/router/asyncRoutes";//格式同routes
import store from "@/store";
const creatRouter =()=>{
return createRouter({
history: createWebHistory(process.env.BASE_URL),
routes:baseRoutes
})
}
let router = creatRouter();
//重置路由:清空user 创建新的router store清空routes记录
export function resetRouter():void {
sessionStorage.setItem('user','')
router = creatRouter()
store.commit('set_allRoutes',[])
}
export default router
2.身份判断:在router.beforeEach守卫中进行判断,这个配置不一定必须写在router/index.ts中,可以单独创建
//前提:需要导入router store asyncRoutes(类似正常的routes对象) reset函数(用
//于重置路由,重置store仓库的值)
router.beforeEach(
(to,from,next)=>{
//判断是不是要去首页,去首页的话就重置路由然后跳转
if(to.path =='/login'||to.path==''){
resetRouter()
next()
return
}
//不是去首页的话,判断store仓库中的allroutes是不是有值了,如果有说明已经构造过了,就跳转
if(store.state.allRoutes&&store.state.allRoutes.length>0){
next()
}else {
//没有构造过需要重新配置
//从sessionStorage中取出user,如果长度大于3就认为是管理员,新增管理路由
const user: string | null = sessionStorage.getItem('user');
if(user){
if (user.length > 3) {
for (const item of asyncRoutes) {
//vue-router4.0取消了addroutes方法,需要通过循环遍历异步路由表然后addroute添加
//注:权限判断条件可以自己改,也可以结合在异步路由表中添加meta.peimissionid的方式过滤路由
//发挥空间很大,这里只是提供了思路
router.addRoute(item)
}
}
}
//将更新后的路由提交给store,后续展示中组件会从store中取
store.commit('set_allRoutes', router.getRoutes());
//这句话的意思:跳过这一次,重新验证 由于已经配置了routes,所以下一次直接跳转
next({...to, replace: true});
}
});
3.展示路由
创建navbar组件(在这里我使用了a标签而不是router-link,router-link实测有点问题,跳转manage显示空白页,手动刷新一次页面的话整个应用又正常了,很奇怪)
<template>
<div>
<a v-for="item in this.$store.state.allRoutes" :href="item.path" :key="item" class="link">{{item.meta?item.meta.title:''}}</a>
</div>
</template>
在Home中导入注册使用
4.结果展示:
当我们输入一个11,点击登录
并且即使手动在导航栏输入http://localhost:8080/manage也不会显示,因为路由中不包含这一项
而当我们输入1111,点击登录
此时 不管是点击还是地址栏输入/manage,都可以访问到
附部分代码:
login.vue登录函数:
handleLogin() {
if(this.account.trim()){
sessionStorage.setItem('user', this.account)
this.$router.push('/home');//设置好user之后这里直接跳转,其他的交给路由导航守卫
}else {
alert("cuowu")
}
}
store仓库:
import {createStore} from 'vuex'
const state = {
allRoutes:[],
name:'shenxk'
};
const mutations = {
set_allRoutes(state:any,payload:any){
state.allRoutes = payload
}
}
const options = {
state,
mutations
}
const store = createStore(options)
export default store
更多推荐
所有评论(0)