一、导航守卫
导航守卫:导航是正在发生变化的路由;从当前的组件离开准备去往下一个组件;
什么需要导航守卫?
真实项目中,我们需要根据用户权限、登录状态来决定用户可以看到的页面;但是路由就在浏览器地址栏里面,如果不加以拦截,用户通过在地址栏中输入,就可以看到他本不该看到的页面;所以我们使用导航守卫拦截它;
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><router-link to="/articles/1/x?name=mabin&age=18">文章1</router-link><button @click="toArticle">去文章1</button><router-view></router-view></div><template id="listTpl"><div><div>LIST <button @click="goBack">返回</button></div><div><router-link to="/list/view">查看</router-link><router-link to="/list/modify">修改</router-link></div><router-view></router-view></div></template><script src="vue.js"></script><script src="vue-router.js"></script><script>let home = {template: `<div>HOME <button @click="toList">去列表</button></div>`,methods: {toList() {// 用方法切路由,push 是去指定的路由this.$router.push('/list')}}};let list = {template: `#listTpl`,methods: {goBack() {// 返回上一页(上一个组件)this.$router.go(-1);}}};let view = {template: `<div>查看</div>`};let modify = {template: `<div>修改</div>`};let articles = {template: `<div>第{{$route.params.id}}篇文章</div>`,created() {console.log(this.$route.params);console.log(this.$route.query);}};// /articles/1/xlet routes = [{name: 'articles',path: '/articles/:id/:text',component: articles},{path: '/',component: home},{path: '/home',component: home},{path: '/list',component: list,children: [{path: 'view',component: view},{path: 'modify',component: modify}]}];let router = new VueRouter({routes});// 全局前置导航守卫: 对所有的路由都生效;router.beforeEach((to, from, next) => {// to 路由对象,包含将要去往的路由的信息// from 路由对象,包含了正要离开的路由的信息// next 控制权函数,如果通过验证执行 next() 交出控制权;console.log(to);console.log(from);// console.log(next);// 在这个函数中就可以做拦截,例如从 cookie 中获取登录状态,如果登录了,执行 next() 交出控制权;// next() 没有任何问题,交出控制权// next(false) 中断当前导航,如果 url 发生变化,会回退到当前页面的路由// next(路由或路由对象) 直接重定向到指定的路由// 无论哪种情况都要执行对应的 next,如果不执行就会处于挂起状态;let isLogin = document.cookie.includes('isLogin=true');// debugger;if (to.fullPath === '/list/view') {// /list/view 假设现在不需要验证权限,所以访问 /list/view 直接放行next()} else {if (isLogin) {next()} else {// next('/list/view'); // 重定向到 viewnext(false); // 中断导航,不能从当前页离开}}// next();});let vm = new Vue({el: '#app',router,methods: {toArticle() {// 点击 router-link 和执行下面的方法效果一样this.$router.push({name: 'articles',params: {id: 1, text: 'x'},query: {name: 'mabin',age: 18}})}}})</script></body></html>
二、路由独享守卫
<body><div id="app"><router-link to="/home">首页</router-link><router-link to="/about">关于</router-link><router-view></router-view></div><script src="vue.js"></script><script src="vue-router.js"></script><script>let home = {template: `<div>HOME</div>`};let about = {template: `<div>About</div>`};// 配置路由映射表let routes = [{path: '/',component: home},{path: '/home',component: home},{path: '/about',component: about,beforeEnter(to, from, next) {// 路由独享守卫:配置在路由映射表中console.log(to);console.log(from);console.log(next);// 在这个钩子中做校验,如果校验通过执行 next() 否则 next(false) 或者 重定向到某一个路由;next(); // 没问题放行// next(false); // 中断导航// next('/home'); // 重定向到某个路由// 无论执行哪一种 next,都要执行一个;}}];// 创建 VueRouter 实例let router = new VueRouter({routes});let vm = new Vue({el: '#app',router})</script></body>
三、组件内守卫
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div id="app"><router-link to="/home">首页</router-link><router-link to="/about/12">关于12</router-link><router-link to="/about/13">关于13</router-link><router-view></router-view></div><script src="vue.js"></script><script src="vue-router.js"></script><script>let home = {template: `<div>HOME</div>`};let about = {template: `<div>About</div>`,beforeRouteEnter(to, from, next) {// 在渲染路由对应的该组件前被调用,// 不!能!访问 this,因为此时 vue 实例尚未创建// to/from/next 和全局守卫一样的意义// next();// next(false);// next('/home')next();},beforeRouteUpdate(to, from, next) {// 当前路由发生改变,但是组件被复用(没销毁)时被调用;适用于动态路由的参数发生变化时// 要去往的路由参数 to.params// 正要离开的路由的参数 from.paramsconsole.log(to.params.id);console.log(from.params.id);next()},beforeRouteLeave(to, from, next) {// 导航要离开当前组件对应的路由时调用,从当前页去往其他页面的时候调用;可以用来做离开时提示用户信息没保存;let doLeave = confirm('信息尚未保存,确定要离开吗?');if (doLeave) {next()}}};// 配置路由映射表let routes = [{path: '/',component: home},{path: '/home',component: home},{path: '/about/:id',component: about,}];// 创建 VueRouter 实例let router = new VueRouter({routes});let vm = new Vue({el: '#app',router})</script></body></html>
四、Vue-cli

