简版vue-router

114 阅读1分钟

srouter-link.js

export default{
  props: {
    to: {
      type: String,
    },
  },
  created() {},
  render(h) {
    return h("a", { attrs: { href: `#${this.to}` } }, this.$slots.default);
  },
}

srouter-view.js

export default{
  render(h) {
    const {routeMap,current}=this.$router;
    const component=routeMap[current]?routeMap[current].component:null;
    return h(component);
  },
}

srouter.js

import Link from "./srouter-link";
import View from "./srouter-view";
let Vue;
class Srouter {
  constructor(options) {
    //把current数据变成相应式
    this.routeMap = {};
    options.routes.forEach(route => {
      this.routeMap[route.path] = route;
    });
    const initial = window.location.hash.slice(1) || "/";
    Vue.util.defineReactive(this, "current", initial);
    window.addEventListener("hashchange", this.onhashchange.bind(this));
    window.addEventListener("load", this.onhashchange.bind(this));
  }
  onhashchange() {
    this.current = window.location.hash.slice(1);
  }
}
Srouter.install = function(_vue) {
  Vue = _vue;
  //mixin可延迟执行代码,Vue.use(router)在new Vue 前,固此时$options无值
  Vue.mixin({
    beforeCreate() {
      if (this.$options.router) {
        Vue.prototype.$router = this.$options.router;
      }
    }
  });
  //注册router-link组件
  Vue.component("router-link", Link);
  //注册router-view组件
  Vue.component("router-view", View);
};

export default Srouter;

index.js使用

import Vue from "vue";
import VueRouter from "./srouter";
import Home from "../views/Home.vue";

Vue.use(VueRouter);

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

const router = new VueRouter({
  routes
});

export default router;