赞
踩
在之前完成的Vue项目中,用到了动态路由。总结了一下特发这篇文章整理思路
此文章分享的是第一种类型。
先说一下使用场景和思路:
例如一个管理系统,需要根据用户登录返回的权限等级然后动态的更改routes中的路由对象,根据用户的权限让用户看到该看到的页面。
用到的技术:
Vuex、Router、localStorage,和一些关键函数(push、addRoutes)
这只是一个小案例,所以只是模拟的后台数据,数据如下:
src/data/data.js
export const loginByUserInfo=[
{id:1,"username":"admin",pawssord:"1234","role":"A"},
{id:2,"username":"xiaohong",pawssord:"1234","role":"B"},
{id:3,"username":"xiaoming",pawssord:"1234","role":"C"}
]
字段role为该用户的权限等级(分为三个权限A、B、C)
现在数据有了,那么就可以实现用户登录了。
Login.vue
export default { data() { return { loginForm: { username: "admin", password: "1234", }, }; }, methods: { login() { //点击登录执行此方法 this.$store .dispatch("index/userLongin", this.loginForm) //调用Vuex中actions中userLongin方法验证 .then((res) => { if (res) { console.log("登录成功!"); this.$router.push({ path: "/" }); } }) .catch((error) => { if (!error) { console.log("登录失败!"); } }); }, }, };
template中的代码块就不贴上来了(太简单了)
当用户点击登录按钮,调用Vuex中定义的验证方法,返回一个Promise对象,验证是否登陆成功。
src/store/login
import { loginByUserInfo } from "../../data/data" //获取data数据 const state = { username: "", //用户名 role: "", //登录用户的权限 newrouter: [] //过滤好的路由规则 } const mutations = { // 保存用户名到vuex SET_USERNAME(state, username) { state.username = username }, // 保存权限到vuex SET_ROLE(state, role) { state.role = role; }, // 保存路由规则vuex SET_NEWROUTER(state, newrouter) { state.newrouter = newrouter; } } const actions = { // info:传过来的账号和密码 userLongin({ commit }, info) { //验证是否登录成功 console.log(info); var data = null; var count = 0; for (let index = 0; index < loginByUserInfo.length; index++) { if (info.username == loginByUserInfo[index].username && info.password == loginByUserInfo[index].pawssord) { // 验证登录是否成功 return new Promise((resolve) => { commit("SET_USERNAME", loginByUserInfo[index].username); // 保存用户名到Vuex commit("SET_ROLE", loginByUserInfo[index].role); // 保存权限到vuex localStorage.setItem("username", loginByUserInfo[index].username); // 保存用户名到本地 localStorage.setItem("role", loginByUserInfo[index].role); // 保存权限到本地 data = { username: loginByUserInfo[index].username, role: loginByUserInfo[index].role } // 返回用户名和权限 resolve(data); }) } if (info.username != loginByUserInfo[index].username || info.password != loginByUserInfo[index].pawssord) { count++; } } if (count == loginByUserInfo.length) { //验证登录失败 return new Promise((resolve,reject) => { reject(data) }) } }, roles({ commit }, newrouter) { //最后把过滤的路由存储路由到Vuex中 console.log(newrouter); return new Promise((resolve, reject) => { commit("SET_NEWROUTER", newrouter); localStorage.getItem("quanxiang", newrouter); resolve(newrouter); }) } } export default { namespaced: true, state, mutations, actions, }
在state中定义好变量接收用户登录成功后接收用户名、用户权限。newrouter在这个时候还没有赋值,是在用户登录成功后页面跳转触发router.beforeEach()全局路由导航守卫时,使用一些判断和filter过滤后再赋值,你可以仔细看最上面Login.vue中的代码。(登录成功页面会跳转触发router.beforeEach()全局路由导航)
src/store/store.js
import Vue from "vue" import Vuex from "vuex" Vue.use(Vuex); import index from "./login/index.js" // import getters from "./getters" export const store=new Vuex.Store({ modules:{ index, }, getters:{ username:state=>state.index.username, role:state=>state.index.role, newrouter:state=>state.index.newrouter } })
这里使用了vuex中的modules概念,src/store/login/index.js只是一个‘小仓库’会被外面的‘大仓库’src/store/store.js集中管理。
src/router/index.js
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) const Login=()=>import("@/components/Login") const Blue=()=>import("@/components/pages_child/Blue") const Main=()=>import("@/components/Main") const Red=()=>import("@/components/pages_child/Red") const Yellow=()=>import("@/components/pages_child/Yellow") //不管什么权限,都可以访问的登录路由 export default new Router({ mode:"history", routes: [ { // 登录路由规则 path: '/login', component: Login, }] }) // 定义动态路由规则 export const pwerRouter=[{ // 跟组件 path:"/",component:Main,redirect:"/red",hidden:false, children:[ // 跟组件下面的子组件 可修改 {path:"/red",name:"red",component:Red}, {path:"/Yellow",name:"Yellow",component:Yellow,meta:{role:"B"}}, {path:"/Blue",name:"Blue",component:Blue,meta:{role:"C"}}, ] }]
src/router/index.js中定义好路由规则并返回,pwerRouter则是需要过滤的路由集合。
那么就要对pwerRouter进行过滤了(关键代码来了)
main.js 核心代码
import Vue from 'vue' import App from './App' // 引用自定义动态路由 import {pwerRouter} from './router/index' // 引用登录路由 import router from "./router/index" // 引用vuex 包含了小仓库 import {store} from "./store/store.js" // 定义全局导航守卫 根据权限用来动态的改变路由规则 router.beforeEach((to,from,next)=>{ // 每次跳转都会进入这个方法验证 // 判断是否有权限 if(store.getters.role){ //拿到用户权限进行判断 // 已经存储路由规则到vuex中,就响应的跳转(该去哪就去哪) if(store.getters.newrouter.length!=0){ next(); }else{ //进行判断和过滤 let newrouter; //这里的根据项目页面的权限进行判断和过滤 //因为我的小案例是规定A权限的用户可以看到所有页面 if(store.getters.role=="A"){ newrouter=pwerRouter; } // 否则就是要过滤路由规则的 else{ let newchild=pwerRouter[0].children.filter(myroute=>{ // 根据filter方法判断留下还是删除该路由 if(myroute.meta){ // 如果用户拥有该选取,并且该权限可以看到这个路由,则留下该路由,否则删除 if(myroute.meta.role==store.getters.role){ return true; } return false; } else{ return true; } }) console.log(newchild); newrouter=pwerRouter; // 接收删除后的路由规则 pwerRouter[0].children=newchild; } router.addRoutes(newrouter); //拼接路由到Routers // 最后把路由存储到vuex中 store.dispatch("index/roles",newrouter).then(res=>{ // 跳转到对应的路由 next({...to}); }) } } // 没有权限 就先登录 else{ if(["/login"].indexOf(to.path)!=-1){ //如果在登录页跳转登录页 next(); //还是跳转到登录页 }else{ next("/login"); } } }) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
当用户登录成功后触发页面跳转,会触发router.beforeEach()路由守卫进行判断和filter过滤。
具体怎么判断就需要根据项目权限需要进行判断了,因为这只是个小案例 (只模拟了3个权限级别,A权限可以访问所有页面,B权限可以访问Red、Yellow页面,C权限可以看到Red、Blue页面),所以判断就比较简单,也比较随意。
router.addRoutes(newrouter); 方法把进行过滤的路由追加到Router对象中。
再调用actions中定义的roles方法,把过滤的路由存储到Vuex中,并且跳转到对应的页面中。
到这里已经完成了根据用户的权限进行判断,并且已经存储到Router对象中和Vuex中
接下来就是把Vuex中的路由渲染到页面,用户点击跳转到对应的页面
src/components/Main.vue
<template> <div id="mainbox"> <router-link id="div" v-for="imter in newrouter[0].children" :to="imter.path" :key="imter.id" > {{ imter.name }} </router-link> <br /><br /> <button v-on:click="stop">退出登录</button> <br/><br/> <router-view></router-view> </div> </template> <script> export default { data() { return {}; }, created() {}, computed: { newrouter() { // 监听Vuex中的路由变化就返回当中的路由渲染到页面 return this.$store.getters.newrouter; }, }, methods: { stop() { this.$router.go(0); }, }, }; </script>
思路简单易懂,希望对大家有帮助。
最后附上效果图

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。