Vue3.0教程 (四)vue-router4 路由守卫和路由菜单

vue-router使用

一、安装

npm

npm install vue-router@4

yarn

yarn add vue-router@4
 "vue-router": "4.0.14"

二、创建文件名router/index.js

import { createWebHistory, createRouter } from 'vue-router'
// createWebHistory  相当于router3的 'history'  '/index'
// createWebHashHistory 相当于router3的 'hash'   '/#/index'
// createMemoryHistory  相当于 router3的 'memory' ''

// 公共路由
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('../views/login.vue'),
    hidden: true
  },
  {
    path: "/:pathMatch(.*)*",
    component: () => import('../views/error/404.vue'),
    hidden: true
  },
  {
    path: '/401',
    component: () => import('../views/error/401.vue'),
    hidden: true
  },
];
 
const router = createRouter({
  history: createWebHistory(),
  routes: constantRoutes,
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0 }
    }
  },
});

export default router;

三、main.js 注册

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')

修改app.vue文件

<template>
  <router-view />
</template>

四、导入函数(rouer 的使用)

import { useRoute, useRouter } from 'vue-router'

五、注释

// 返回当前路由地址。相当于在模板中使用 $route。必须在 setup() 中调用。
const $route = useRoute()  // 返回当前路由地址

// 返回 router 实例。相当于在模板中使用 $router。必须在 setup() 中调用。
const $router = useRouter() // 返回 router 实例
// 执行路由跳转等功能
$router.push('/')

六、监听当前路由发生变化

watch($route, () => {
	// $route
    // 路由发生改变
})

七、router方法

// 跳转
$router.push({path:'/'})
// 
$router.replace({ path: '/redirect' + view.fullPath })

八、路由守卫

import router from './index'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// import { getToken } from '@/utils/auth'
import useUserStore from '@/store/modules/user'
import usePermissionStore from '@/store/modules/permission'
import { isHttp } from '@/utils/validate'

NProgress.configure({ showSpinner: false })
// 白名单
const whiteList = ['/login', '/auth-redirect', '/bind', '/register']

// 路由守卫
router.beforeEach((to, from, next) => {
  // 进度条
  NProgress.start()
  // if (getToken()) {
  if (true) {
     // 已登录且要跳转的页面是登录页
     if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else{
      // 是否存在token
      if (useUserStore().roles.length === 0) {
        // 没有拉取用户信息
        useUserStore().getInfo().then(() => {
            // 获取菜单列表
            usePermissionStore().generateRoutes().then((accessRoutes) => {
              // 根据roles权限生成可访问的路由表
              accessRoutes.forEach((route) => {
                if (!isHttp(route.path)) {
                  router.addRoute(route) // 动态添加可访问路由表
                }
              })
              next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
            })
          })
          .catch((error) => {
            // 获取用户信息失败 登出并重定向/
            useUserStore().logOut()  .then(() => {
                next({ path: '/' })
              })
          })
      } else {
        //路由、菜单加载ok
        next()
      }
    }
    
  } else {
    // 没有token
    if (whiteList.indexOf(to.path !== -1)) {
      //白名单直接跳转
      next()
    } else {
      // 其他菜单跳转值登录界面
      next(`/login?redirect=${to.fullPath}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

store说明

1.user.js

// 引入 defineStore
import {defineStore} from 'pinia'
const useUserStore = defineStore('user',{
    state:()=>({ 
        name: 'admin',
        userId:'111111',
        avatar: '',
        roles: [],
        user:null,
    }),
    actions:{
        // 退出
        logOut() {
          // 使用 state 通过this
          return new Promise((resolve, reject) => {
          })
        },

        // 获取用户信息
        getInfo(){
          return new Promise((resolve,reject)=>{
            // 拉取信息
            this.user = {username:'admin',userid:'admin'};
            this.roles = ['ROLE_DEFAULT']
            resolve()
          })
        }
    }
})
// 导出
export default useUserStore

2.permission.js

// 引入 defineStore
import { defineStore } from 'pinia'
import { constantRoutes } from '@/router'
import routerAll from '@/router/router-all'  

const usePermissionStore = defineStore('permission', {
  state: () => ({
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],
  }),
  actions: {
    setSidebarRouters(routes) {
      this.sidebarRouters = routes
    },
    generateRoutes(){
      return new Promise(resolve=>{
        // 向后端请求路由数据
        // 目前我们先写死
        setTimeout(() => {
        this.setSidebarRouters(constantRoutes.concat(routerAll))
          resolve(routerAll)
        }, 1000);
      })
    }
  },
})
// 导出
export default usePermissionStore

3.routerAll.js ( src /router/router-all)

/**
 * 本地所有的路由,用于与线上的路由合并参数
 */
const routerAll = [
  {
    path:'/nested',
    component: () => import('../layout'),
    name:"nested",
    meta: { title: '菜单管理', icon: 'user' },
    children:[
      {
        path: 'menu1',
        name: 'menu1',
        component: () => import('@/views/nested/menu1/menu1-1'),
        meta: { title: '菜单1', icon: 'user' }
      },
      {
        path: 'menu2',
        name: 'menu2',
        component: () => import('@/views/nested/menu1/menu1-2'),
        meta: { title: '菜单1', icon: 'user' }
      },
    ]
  }
]
export default routerAll

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值