【vue3基础】vue-router4的配置和动态路由

文章简介

针对vue-router4的简单配置,基本路由的配置和后端获取路由后的渲染进行简单的配置,路由跳转前的验证功能。

安装

npm install vue-router@4

配置

  1. src 文件下创建 router/index.js 文件。
import { createRouter, createWebHashHistory } from 'vue-router'
// 本地静态路由配置
export const routes = [
  {
    path: '/',
    redirect: '/home'
  },
  {
    path: '/login',
    component: () => import('@/views/login.vue'),
  },
  {
    path: '/home',
    component: () => import('@/views/home.vue'),
  },
  {
    path: '/:pathMatch(.*)*',
    component: () => import('@/views/404.vue'),
  }
]

// 创建路由实例
const router = createRouter({
  history: createWebHashHistory(),
  routes: routes,
})

export default router
  1. main.js 中配置
// 引入路由
import router from './router'
app.use(router)

路由拦截配置

可以写在 router/index.js 中,也可以单独创建一个文件 permission.js 写,根据个人需求决定, 文件名称按你喜欢的写,单独写的话要在 main.js 中引入。

...
... 省略以上代码
// 配置路由白名单
let whiteList = ['/login']

// 路由拦截
router.beforeEach((to, from, next) => {
  // 白名单-> 直接放行
  if (whiteList.includes(to.path)) {
    return next()
  }

  // 如果没有token,跳转到登录页面并携带当前路由的path作为参数
  if (!token) {
    return next('/login?redirect=' + to.path)
  }

  // 有token,有菜单 -> 直接放行
  if (menuList && userStore.menuList.length > 0) {
    return next()
  }

  // 有token,无菜单 -> 请求路由数据并渲染路由
  loadMenu(to, next)
})

// 路由跳转后的事件
router.afterEach((to, from) => {
  // ...操作根据需求决定
})

动态请求路由配置

// 处理请求的数据
function asyncRoutesHandler(routes) {
  return routes.map(route => {
    // 先处理菜单的属性(meta,keepAlive等)=> 处理逻辑省略。。。
    // 动态加载组件
    if (route.component === 'Layout') {
      route.component = Layout
    } else {
      const component = route.component
      route.component = modules[`/src/views${component}.vue`]
    }
    // 递归处理子路由
    if (route.children && route.children.length > 0) {
      route.children = asyncRoutesHandler(route.children)
    }
    // 返回处理后的路由
    return route
  })
}

// 请求菜单数据
async function loadMenu(to, next) {
  let res = await getMenuList()
  // 处理请求的数据(layout、children、path、name等)
  let asyncRoutes = asyncRoutesHandler(res.data)
  // 添加路由
  asyncRoutes.forEach(item => {
    router.addRoute(item)
  })
  // 添加404页面
  router.addRoute(NotFound)
  // 添加到options.routes中,防止渲染菜单的时候拿不到
  router.options.routes = [...routes, ...asyncRoutes]
  // ...to浅拷贝to的对象 , replace: true 禁止浏览器记录路由记录,防止重复刷新
  next({ ...to, replace: true })
}

完整代码如下

import { createRouter, createWebHashHistory } from 'vue-router'

const modules = import.meta.glob('/src/views/**/**.vue')
// 404页面提出来最后插入,防止先路由先匹配404页面
const NotFound = {
  path: '/:pathMatch(.*)*',
  name: '404',
  component: () => import('@/views/404.vue'),
}

// 本地静态路由配置
const routes = [
  {
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    component: () => import('@/views/home/index.vue'),
  },
]

// 创建路由实例
const router = createRouter({
  history: createWebHashHistory(),
  routes: routes,
})

// 配置路由白名单
let whiteList = ['/login']

// 路由拦截
router.beforeEach((to, from, next) => {
  // 白名单-> 直接放行
  if (whiteList.includes(to.path)) {
    return next()
  }

  // 如果没有token,跳转到登录页面并携带当前路由的path作为参数
  if (!token) {
    return next('/login?redirect=' + to.path)
  }

  // 有token,有菜单 -> 直接放行
  if (menuList && userStore.menuList.length > 0) {
    return next()
  }

  // 有token,无菜单 -> 请求路由数据并渲染路由
  loadMenu(to, next)
})

// 处理请求的数据
function asyncRoutesHandler(routes) {
  return routes.map(route => {
    // 先处理菜单的属性(meta,keepAlive等)
    // 处理逻辑省略。。。

    // 动态加载组件
    if (route.component === 'Layout') {
      route.component = Layout
    } else {
      const component = route.component
      route.component = modules[`/src/views${component}.vue`]
    }

    // 递归处理子路由
    if (route.children && route.children.length > 0) {
      route.children = asyncRoutesHandler(route.children)
    }

    // 返回处理后的路由
    return route
  })
}

// 请求菜单数据
async function loadMenu(to, next) {
  // 这里会引入仓库,然后存储请求回来的路由,防止每次刷新都请求  
  const userStore = useUserStore() // 存储路由数据的仓库  我用的pinia
  
  let res = await getMenuList() // 请求路由数据
  
  userStore.setMenuList(res.data) // 用自己的方法把数据塞到仓库就行
  
  // 处理请求的数据(layout、children、path、name等)
  let asyncRoutes = asyncRoutesHandler(res.data)
  // 添加路由
  asyncRoutes.forEach(item => {
    router.addRoute(item)
  })
  // 添加404页面
  router.addRoute(NotFound)
  // 添加到options.routes中,防止渲染菜单的时候拿不到
  router.options.routes = [...routes, ...asyncRoutes]
  // ...to浅拷贝to的对象 , replace: true 禁止浏览器记录路由记录,防止重复刷新
  next({ ...to, replace: true })
}


// 路由跳转后的事件
router.afterEach((to, from) => {
  // ...操作根据需求决定
})

export default router
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值