文章目录
有关路由的相关配置 ( 路由懒加载和路由鉴权 )
/router/index.js
-
Vue2.x 中:
import Vue from 'vue' import Router from 'vue-router' import { getStore } from 'js/store' Vue.use(Router); var router = new Router({ routes: [ { path: '*', redirect: '/' }, { path: '/', name: '/', component: () => import('./views/Index.vue'), // vue路由懒加载 异步加载 meta: { title: '首页', requireAuth: true // 只要此字段为true,必须做鉴权处理 } }, { path: '/test', name: 'test', component: () => import('./views/Test.vue'),// vue路由懒加载 异步加载 meta: { title: 'test', requireAuth: true // 只要此字段为true,必须做鉴权处理 } }, { path: '/login', name: 'login', component: () => import('./views/Login.vue'),// vue路由懒加载 异步加载 meta: { noNav: true // 不显示nav } }] }); let indexScrollTop = 0; router.beforeEach((to, from, next) => { // 路由鉴权:在路由meta对象中由个requireAuth字段,只要此字段为true,必须做鉴权处理 if (to.matched.some(res => res.meta.requireAuth)) { const token = getStore({ name: 'access_token', type: "string" });// 获取localstorage中的access_token console.log(token); // 路由进入下一个路由对象前,判断是否需要登陆 if (!token) { // 未登录 next({ path: '/login', query: { redirect: to.path // 将跳转的路由path作为参数,登录成功后再跳转到该路由 } }) } else { // 用户信息是否过期 let overdueTime = token.overdueTime; let nowTime = +new Date(); // 登陆过期和未过期 if (nowTime > overdueTime) { // 登录过期的处理,君可按需处理之后再执行如下方法去登录页面 // 我这里没有其他处理,直接去了登录页面 next({ path: '/login', query: { redirect: to.path } }) } else { next() } } } else { next() } if (to.path !== '/') { // 记录现在滚动的位置 indexScrollTop = document.body.scrollTop } document.title = to.meta.title || document.title }) router.afterEach(route => { if (route.path !== '/') { document.body.scrollTop = 0 } else { Vue.nextTick(() => { // 回到之前滚动位置 document.body.scrollTop = indexScrollTop }) } }) export default router;
-
Vue3.x 中:
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'; const routes = [ { path: '/', name: 'Index', meta: { title: '首页', requireAuth: true }, component: () => import(/* webpackChunkName: "index" */ '@/views/index/Index') }, { path: '/index', redirect: { name: 'Index' } // 重定向 }, { path: '/login', name: 'Login', meta: { title: '登录', fullscreen: true }, component: () => import(/* webpackChunkName: "login" */ '@/views/login/Login'), beforeEnter(to, from, next) { // 局部路由守卫 const { token } = sessionStorage; token ? next({ name: 'Index' }) : next(); // 已登录直接进入主页 } }, { path: '/userlist', name: 'UserList', meta: { title: '用户管理', keepAlive: true, requireAuth: true }, component: () => import(/* webpackChunkName: "user" */ '@/views/user/List') }, { path: '/:pathMatch(.*)*', name: 'NotFound', meta: { title: '404', fullscreen: true }, component: () => import(/* webpackChunkName: "notFound" */ '@/views/404/Index') } ]; const router = createRouter({ // history: createWebHashHistory(), history: createWebHistory(), routes }); // 全局路由守卫 let indexScrollTop = 0; router.beforeEach((to, from, next) => { const { token } = sessionStorage; if (to.matched.some(res => res.meta.requireAuth)) { if (token || to.name == 'Login') { // 已经登录、登录页 => next() next(); } else { next({ name: 'Login' }); } } else { next(); } if (to.path !== '/') { indexScrollTop = document.body.scrollTop; } document.title = to.meta.title || document.title }); router.afterEach(route => { if (route.path !== '/') { document.body.scrollTop = 0; } }); router.onError(error => { const pattern = /Loading chunk (\d)+ failed/g; const isChunkLoadFailed = error.message.match(pattern); const targetPath = router.history.pending.fullPath; if (isChunkLoadFailed) { location.reload(); // router.replace(targetPath); } }); export default router;
路由懒加载的不同写法
1. webpack < 2.4版(vue-cli2)的懒加载
const Index = resolve => require(['./views/Index.vue'], resolve)
2. webpack > 2.4版(vue-cli3)的懒加载
const Index = () => import('./views/Index.vue')
其他路由知识点
1. router-link
<router-link :to="{name:'entityList', query:{page: 'Ecp.SystemMessage.List.vdp'}}" tag="li"></router-link>
- 在 HTML5 history 模式下使用了 base 选项,所有 to 属性可以不用写基路径
- 会拦击点击事件,不会重新加载页面.
- router-link 默认渲染为 a 标签,我们可以通过 tag 属性设置为别的标签(常用的li).
- to 属性可以绑定 name (命名组件), query (带查询参数)
2. router-view
<transition name="fade" mode="out-in" key="$route.path">
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
- router-view: 渲染匹配到的视图组件,router-view匹配到的视图组件里面还可以嵌套自己的router-view.根据嵌套路径(children)来继续渲染.
- router-view可以通过name属性来渲染对应的component下相应的组件
- router-view可以配合transition与keep-alive使用,如果同时使用,里面要使用keep-alive.
- keep-alive缓存router的请求