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