Vue3 权限路由 动态路由

563 阅读2分钟

权限路由

通过路由里的Meta来定义当前路由的权限来判断是否能进入改路由

技术栈:Vue3PiniaVueRouter4axios

//router.ts


import { createRouter, createWebHashHistory, RouteRecordRaw, NavigationGuardNext, RouteMeta } from "vue-router"
import { useStore } from "../store/index"
import axios from "axios"
const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    redirect: "/login"
  },
  {
    path: "/login",
    name: "Login",
    component: () => import("../view/login/Login.vue")
  },
  {
    path: "/home",
    name: "Home",
    redirect: "/test1",
    component: () => import('../view/home/Home.vue'),
    children: [
      {
        path: "/test1",
        name: 'Test1',
        meta: {
          auth: ['admin', 'admin2']
        },
        component: () => import("../view/test/Test1.vue")
      },
      {
        path: "/test2",
        name: 'Test2',
        meta: {
          auth: ['admin', 'admin2']
        },
        component: () => import("../view/test/Test2.vue")
      },
      {
        path: "/test3",
        name: 'Test3',
        component: () => import("../view/test/Test3.vue")
      }
    ]
  },
  {
    path: "/404",
    component: () => import("../view/test/404.vue")
  }
]

// 白名单
const whiteList: Array<string> = ['/login', '/404', '/home']
const router = createRouter({
  history: createWebHashHistory(),
  routes
})
router.beforeEach(async (to, from, next) => {
  // 1.判断是否访问白名单
  if (whiteList.includes(to.path)) return next()
  // 2.不是白名单页面则需要登录
  // 获取token
  const token = localStorage.getItem("token")
  if (!token) return next("/login")
  const store = useStore()
  // 获取状态机里的用户信息
  const userInfo = store.state.userInfo
  if (!userInfo.id) {
    const { data: res } = await axios({
      url: "https://xxx.xxx.com",
      method: "POST",
      data: {},
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
    // 用户信息获取失败,跳转到登录页
    if (res.code != 1) return next('/login')
    store.updateUserInfo({ id: 1,auth:"admin" })
    // auth:表示用户的权限等级
    const auth = 'admin'
    // 判断去往的页面的权限等级是否匹配上
   //  authentication(to.meta, next, auth)

  } 
 // else {
    // 这里
 //   authentication(to.meta, next, 'admin')
  //}
  
  authentication(to.meta, next, store.state.userInfo.auth as string)
})
//身份验证
function authentication(meta: undefined | RouteMeta, next: NavigationGuardNext, auth: string): void {
  if (meta && meta.auth && (meta.auth as string[]).includes(auth)) {
    next()
  } else {
    next("/404")
  }
}
export default router

动态路由

通过后端返回的路由进行添加

技术栈:Vue3PiniaVueRouter4axios

import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router"
import { useStore } from "../store/index"
import axios from "axios"
const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    redirect: "/login"
  },
  {
    path: "/login",
    name: "Login",
    component: () => import("../view/login/Login.vue")
  },
  {
    path: "/home",
    name: "Home",
    component: () => import("../view/home/Home.vue"),
    children: [
      {
        path: "/home",
        redirect: "/test1"
      }
    ]
  },
  {
    path: "/:error*",
    component: () => import("../view/test/404.vue")
  }
]

const whiteList: string[] = ['/login', '/home', '/404']
const router = createRouter({
  history: createWebHashHistory(),
  routes
})
router.beforeEach(async (to, from, next) => {
  // 判断是否进入白名单
  if (whiteList.includes(to.path)) return next()
  // 判断有token
  const token = localStorage.getItem("token")
  if (!token) return next("/login")
  const store = useStore()
  const userInfo = store.state.userInfo
  // userInfo.id判断当前是否登录过
  if (!userInfo.id) {
    const { data: res } = await axios({
      url: "",
      method: "POST",
      data: {},
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      }
    })
    if (res.code != 1) return next("/login")
    //  更新用户信息,用id:1 表示
    store.updateUserInfo({ id: 1 })
    // 模拟需要添加的路由信息
    const array = [
      {
        path: "/test1",
        name: "Test1",
      },
      // {
      //   path: "/test2",
      //   name: "Test2",
      // },
      {
        path: "/test3",
        name: "Test3",
      }
    ]
    array.forEach(item => {
      router.addRoute("Home", {
        path: item.path,
        name: item.name,
        component: () => import(`../view/test/${item.name}.vue`)
      })
    })
    next({ ...to, replace: true })
  }else{
   next()
  }
  //done:Boolean:表示当前是否添加过路由
  //if (store.state.done) {
  //  next()
 // } else {
    // 进入这里表示正在添加路由
  //  store.updateDone()
    // 模拟需要添加的路由信息
 //   const array = [
  //    {
 //       path: "/test1",
 //       name: "Test1",
//      },
      // {
      //   path: "/test2",
      //   name: "Test2",
      // },
//      {
//        path: "/test3",
//        name: "Test3",
//      }
//    ]
//    array.forEach(item => {
  //    router.addRoute("Home", {
 //       path: item.path,
//        name: item.name,
  //      component: () => import(`../view/test/${item.name}.vue`)
 //     })
//    })
//    next({ ...to, replace: true })
//  }

})
export default router

以上!