关于路由的一些理解
以下面的router下的index.js文件为例。
import Vue from 'vue'; import Router from 'vue-router'; import {publicRoute, protectedRoute} from './config'; import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; import { getToken } from '@/util/auth' const routes = publicRoute.concat (protectedRoute); // 解决两次访问相同路由地址报错 const routerPush = Router.prototype.push Router.prototype.push = function push(location) { return routerPush.call(this, location).catch(error=> error) } Vue.use (Router); const router = new Router ({ mode: 'hash', //hash路由和history路由可选 linkActiveClass: 'active', //用来做选中样式的切换 routes: routes, //路由路径 }); // router gards 路由守卫 router.beforeEach ((to, from, next) => { NProgress.start(); document.title = `某系统-${to.meta.title}` if (to.meta.public) { next() } else { if (to.path != '/login' && (!getToken() || getToken() == 'undefined')) { NProgress.done() next({ path: '/login', }) } else { NProgress.done() next() } } }); router.afterEach ((to, from) => { NProgress.done (); }); export default router;
1. 路由守卫之beforeEach
router.beforeEach()一般用来做一些进入页面的限制。比如没有登录,就不能进入某些页面,只有登录了之后才有权限查看某些页面,说白了就是路由拦截。
每个守卫方法接收三个参数:
to: 即将要进入的目标 路由对象
from: 当前导航正要离开的路由
next: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
路由拦截是我们项目中经常遇到的普遍问题,例如当你访问任何一个页面的时候需要验证该用户有没有登录等;对此,vue-router提供的beforeRouter可以方便的实现路由的导航守卫。
2. active-class
active-class是vue-router模块的router-link组件中的属性,用来做选中样式的切换。
3. NProgress
NProgress是页面跳转是出现在浏览器顶部的进度条
//用法
NProgress.start();
NProgress.done();
4.hash路由和history路由
router有两种模式:hash模式(默认)、history模式(需配置mode: 'history')。两种模式的区别:简单回答:hash模式url带#号,history模式不带#号。
hash 就是指 url 尾巴后的 # 号以及后面的字符。这里的 # 和 css 里的 # 是一个意思。hash 也 称作 锚点,本身是用来做页面定位的,她可以使对应 id 的元素显示在可视区域内。
由于 hash 值变化不会导致浏览器向服务器发出请求,而且 hash 改变会触发 hashchange 事件,浏览器的进后退也能对其进行控制,所以人们在 html5 的 history 出现前,基本都是使用 hash 来实现前端路由的。
已经有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,为什么还要搞个 history 呢?
首先,hash 本来是拿来做页面定位的,如果拿来做路由的话,原来的锚点功能就不能用了。其次,hash 的传参是基于 url 的,如果要传递复杂的数据,会有体积的限制,而 history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中。
history 模式改变 url 的方式会导致浏览器向服务器发送请求,这不是我们想看到的,我们需要在服务器端做处理:如果匹配不到任何静态资源,则应该始终返回同一个 html 页面。