Vue2源码剖析之Vue-Router原理

vue-router的两种实现路由的模式:

一、hash模式

  • hash模式的路由是以#出现,例如localhost:8080/#/home。hash模式的渲染原理首先是配置路由数组list,例如[{path: ‘/home’,name:’home’,component: ‘home.vue’},{path: ‘/about’,name:’about’,component: ‘about.vue’}],根据路由地址选取路由数组对应的项,在页面中会有一个router-view的组件,这个组件会根据路由地址来渲染对应的component,router-view中有一个render(h => h(componernt))方法来渲染对应的component

根据vue-router原理仿写router代码

  • index.js
import Home from "../components/Home.vue";
import Vue from "vue";
import VueRouter from "./router-core";

Vue.use(VueRouter);

const routes = [
  {
    name: "home",
    path: "/",
    component: Home
  },
  {
    name: "about",
    path: "/about",
    component: () => import("../components/About.vue")
  }
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
});

export default router;
复制代码
  • router-core.js

let Vue; 
class VueRouter {
  constructor(options) {
    this.$options = options;
    const initial = window.location.hash.slice("#") || "/";
    Vue.util.defineReactive(this, "current", initial);

    window.addEventListener("hashchange", () => {
      this.current = window.location.hash.slice(1);
      console.log(this.current);
    });
  }
}

VueRouter.install = function(_Vue) {
  Vue = _Vue;
  Vue.mixin({
    beforeCreate() {
      if (this.$options.router) {
        Vue.prototype.$router = this.$options.router;
      }
    }
  });

  Vue.component("router-link", {
    props: {
      to: {
        type: String,
        required: true
      }
    },
    render(h) {
      return h("a", { attrs: { href: "#" + this.to } }, this.$slots.default);
    }
  });
  Vue.component("router-view", {
    render(h) {
      let component = null;
      const route = this.$router.$options.routes.find(
        route => route.path === this.$router.current
      );
      if (route) {
        component = route.component;
      }
      return h(component);
    }
  });
};

export default VueRouter;
复制代码
  • 在main.js中引入router/index.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";

Vue.config.productionTip = false;

new Vue({
  router,
  render: h => h(App)
}).$mount("#app");

复制代码

二、history模式

  • history是浏览器历史记录栈提供的接口,通过back(),forward(),go()等方法,可以读取浏览器历史记录栈的信息,进行各种跳转工作。
window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)
复制代码
  • stateObject:当浏览器跳转到新的状态时,将触发popState事件,该事件将携带这个stateObject参数的副本
  • title:所添加记录的标题
  • url:所添加记录的url
  1. push:与hash模式类似,只是将window.hash改为window.pushState

  2. replace: 与hash模式类似,只是将window.replace改为window.replaceState

  3. 监听地址变化:在Html5History的构造函数中监听popState(window.onpopstate)

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享