vue3静态路由及动态路由的简单配置
- 静态路由配置,是指路由routes放在前端js文件中;
- 动态路由配置,是指路由routes从后端接口获取,动态加载。
app.vue文件的内容
<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
</script>
<template>
<router-view v-slot="{ Component }">
<transition name="el-fade-in" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</template>
<style scoped>
</style>
- 创建src/router/index.js文件
- main.js文件引用src/router/index.js
import router from './router/index'
const app = createApp(App)
app.use(router)
一、静态路由配置
src/router/index.js文件内容(对应的vue文件及文件夹要先创建)
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [{
path: "/",
redirect: "/Index",
meta: { title: '首页' }
}, {
path: "/Index",
name: "Index",
component: () => import('@/views/Index/index.vue'),
meta: { title: '首页' },
children: []
}, {
path: "/Login",
name: "Login",
component: () => import('@/views/Login/index.vue'),
meta: { title: '登录' },
children: []
}, {
path: "/NotFound",
name: "NotFound",
component: () => import('@/views/NotFound/index.vue'),
meta: { title: '404' },
children: []
}, {
path: "/Personal",
name: "Personal",
component: () => import('@/views/Personal/index.vue'),
meta: { title: '个人中心' },
children: []
}]
const router = createRouter({
history: createWebHashHistory(),
routes: routes,
scrollBehavior() {
return {
top: 0
}
}
})
router.beforeEach((to, from, next) => {
// 进入页面前处理(如:进度条,页面条件判断等)
// console.log(to.name);
next()
})
router.afterEach((to, from) => {
// 进入页面后处理(如:进度条结束)
try {
// console.log(to.name);
} catch (err) {
console.log(err, to, from);
}
})
export default router
二、动态路由配置
src/router/index.js文件内容(对应的vue文件及文件夹要先创建)
import { createRouter, createWebHashHistory } from 'vue-router'
import { userStore } from '../store/index.js'
// 此处使用的是pinia储存,(vuex相似,pinia相对使用更方便)
// pinia的具体使用方法此处不做说明
const routes = [{
path: "/",
redirect: "/Index",
meta: { title: '首页' }
}, {
path: "/Index",
name: "Index",
component: () => import('@/views/Index/index.vue'),
meta: { title: '首页' },
children: []
}, {
path: "/Login",
name: "Login",
component: () => import('@/views/Login/index.vue'),
meta: { title: '登录' },
children: []
}, {
path: "/NotFound",
name: "NotFound",
component: () => import('@/views/NotFound/index.vue'),
meta: { title: '404' },
children: []
}]
// 注意:此处routes和静态routes不同之处,动态的路由的routes部分必须有的路由,在这些路由中页面加载其他路由。
const router = createRouter({
history: createWebHashHistory(),
routes,
scrollBehavior() {
return {
top: 0
}
}
})
// 路由拦截
router.beforeEach((to, from, next) => {
const store = userStore()
// 获取pinia中储存的路由数据(1、固定值 2、从登录接口中获取储存的)
// 若是使用vuex,取值方法类似
const list = router.getRoutes()
// 获取当前路由中routes信息,和routes长度对比,若是长度相等,则需要加载动态的路由
if (list.length == routes.length) {
store.menuList.forEach((v) => {
const val = {
...v,
name: v.perms,
meta: { title: v.menuName },
component: eval(`() => import("${v.component}")`)
}
// perms、menuName、component是和后端约定的菜单信息字段,可能是其他值,根据具体情况觉得
// component字段内容是‘/src/views/Personal/index.vue’。
// 建议:perms、menuName字段直接使用name、title更方便。
// 注意:component的引用方法eval()和routes中的引用区别
router.addRoute(val)
})
}
if (!!store.userInfo?.access_token) {
// 根据是否有token(即store.userInfo.access_token)
// 有登录信息
if (to.matched.length > 0) {
// 页面路径存在
next()
} else {
// 页面路径不存在(判断是否是刷新的页面)
const obj = router.getRoutes().find(v => v.path == to.path)
// 此处判断可以用from中path判断,也可以判断obj是否存在
if (!!obj) next(obj.path)
else next('/NotFound')
// 注意:此处判断必须做
// 不做不影响第一次加载,若是刷新页面,则所有动态页面都会跳转404页面
}
} else {
// 无token登录信息,去登录页
if (to.path == '/Login') {
// 当前页面为登录页
next()
} else {
// 当前页面为非登录页
next('/Login')
}
}
})
router.afterEach((to, from) => {
try {
// console.log(to.name);
} catch (err) {
console.log(err, to, from);
}
})
export default router
注:
此文仅适合简单动态路由,如果是复杂的动态路由,如:进度条、路由权限、菜单栏为公共组件等相对复杂的动态路由可以在此基础上添加功能。