vue-router导航守卫进阶&源码实现

栏目: JavaScript · 发布时间: 5年前

内容简介:前端路由实现起来其实很简单,本质就是监听URL的变化,然后匹配路由规则,显示相应的页面,并且无须刷新。vue-router共有三种守卫,分别是全局守卫、路由独享守卫、组件内的守卫。效果等同于全局守卫ep:通过route设置document.title

前端路由实现起来其实很简单,本质就是监听URL的变化,然后匹配路由规则,显示相应的页面,并且无须刷新。vue-router共有三种守卫,分别是全局守卫、路由独享守卫、组件内的守卫。

导航守卫

  • 全局守卫

    你可以使用 router.beforeEach 注册一个全局前置守卫: ep:设置全局守卫,如果进入about页,没有登陆则重定向到login页

router.beforeEach((to,from,next) => {
      console.log(to.meta)
  // 判断是否登录
  if (to.path === '/about' && !window.isLogin) {
    next('/login?redirect='+to.path);
  } else {
    next();
  }
})
复制代码
  • 路由独享守卫
{
      path: "/about",
      name: "about",
      meta: {requireLogin:true},  // meta  取值就是to.meta
      beforeEnter(to,from,next) {
        // 判断是否登录  路由独享守卫
        if (!store.state.isLogin) {
          next('/login?redirect='+to.path);
        } else {
          next();
        }
      },
      component: () =>
        import(/* webpackChunkName: "about" */ "./views/About.vue")
}
复制代码

效果等同于全局守卫

  • 组件内的守卫
export default {
  beforeRouteEnter(to, from, next) {}
  beforeRouteUpdata(to, from, next) {}
  beforeRouteLeave(to, from, next) {}
}
复制代码

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

meta路由元信息

ep:通过route设置document.title

{
    path: '/customer/new',
    name: 'NewCustomer',
    meta: {title: '新增客户'},
    component: () => import('@/Views/CustomerNew')
  },
  
  router.beforeEach(function (to, from, next) {
      if (to.meta && to.meta.title) {
        document.title = ((to.meta && to.meta.title))
      }
      next()
  })
复制代码

hash模式&&history模式

www.test.com/#/ 就是 Hash URL,当 # 后面的哈希值发生变化时,不会向服务器请求数据,可以通过 hashchange 事件来监听到 URL 的变化,从而进行跳转页面。

vue-router导航守卫进阶&源码实现

History 模式是 HTML5 新推出的功能,比之 Hash URL 更加美观

vue-router导航守卫进阶&源码实现

源码实现

应用页面

<router-link to="#/foo">foo</router-link> |
      <router-link to="#/bar">bar</router-link>
复制代码

router配置

const Foo = {
  render() {
    return <div>Foo</div>;
  }
};
const Bar = {
  render() {
    return <div>Bar</div>;
  }
};
export default new TRouter(Vue, {
  routes: [
    { 
      path: "/foo", 
      component: Foo
    },
    {
       path: "/bar",
       component: Bar
    }
  ]
});
复制代码

源码实现

import Vue from "vue";

class TRouter {
  constructor(Vue, options) {
    this.$options = options;
    this.routeMap = {}; // 全局的路由映射  key就是path(唯一的)
    this.app = new Vue({  // 对vue的强依赖
      data: {
        current: "#/"  // 当前路由
      }
    });
    this.init();
    this.createRouteMap(this.$options); 
    this.initComponent(Vue);
  }

  // 初始化 hashchange
  init() {
    // load事件在页面或某个资源加载成功时触发
    window.addEventListener("load", this.onHashChange.bind(this), false);
    // hashchange事件在 URL 的 hash 部分(即#号后面的部分,包括#号)发生变化时触发。
    window.addEventListener("hashchange", this.onHashChange.bind(this), false);
  }

  createRouteMap(options) {
    options.routes.forEach(item => {
      this.routeMap[item.path] = item.component;
    });
  }

  // 注册组件
  initComponent(Vue) {
    Vue.component("router-link", {  // 全局注册
      props: {
        to: String  // 去哪个地址
      },
      render: function (h) { // 传入函数  h 就是createElement
        // <a :href="to"><slot></slot></a>
        // 返回的是虚拟dom
        return h("a", { attrs: { href: this.to } }, this.$slots.default);
      }
    });

    const _this = this;  // 全局this
    Vue.component("router-view", {  // 占位符
      render(h) { // 根据当前路由发生变化  渲染当前组件所匹配的组件
        var component = _this.routeMap[_this.app.current];
        return h(component);
      }
    });
  }

  // 获取当前 hash 串
  getHash() {
    return window.location.hash.slice(1) || "/";
  }

  // 设置当前路径
  onHashChange() {  // 挂载的组件刷新
    this.app.current = this.getHash();  // 获取最新hish赋值
    console.log(this.app.current, 'this.app.current')
  }
}
复制代码

总结

vue-router对vue也是强依赖关系,简单的也可以理解为是对history的封装,本质上还是实现根据路由不同,返回不同内容。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

群体智能

群体智能

James Kennedy、Russell C Eberhart、Yuhui Shi / 人民邮电出版社 / 2009-2-1 / 75.00元

群体智能是近年来发展迅速的人工智能学科领域.通过研究分散,自组织的动物群体和人类社会的智能行为, 学者们提出了许多迥异于传统思路的智能算法, 很好地解决了不少原来非常棘手的复杂工程问题.与蚁群算法齐名的粒子群优化(particle swarm optimization, 简称PSO)算法就是其中最受瞩目,应用最为广泛的成果之一. 本书由粒子群优化算法之父撰写,是该领域毋庸置疑的经典著作.作者......一起来看看 《群体智能》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具