Vue-router的原理以及實(shí)現(xiàn)

Vue-router 是vue主要的核心插件之一,也是SPA應(yīng)用所必須依賴的一個核心插件,至于怎么使用或者說基礎(chǔ)知識,這里不再贅述,我們直接上代碼,下面是模仿實(shí)現(xiàn)的一個Vue-router的插件。

// 引用從install函數(shù)中傳遞進(jìn)來的vue實(shí)例
let Vue;
class VueRouter {
  constructor(options) {
    this.$options = options;
    this.routerMap = {};

    // 主要是利用vue本身的響應(yīng)式來實(shí)現(xiàn),如果current變化,來刷新router-view
    this.app = new Vue({
      data: {
        current: '/',
      },
    });
  }

  createInit() {
    this.bindEvents(); //監(jiān)聽url變化
    this.createRouteMap(this.$options); //解析路由配置
    this.createComponent(); //創(chuàng)建兩個組件
  }
  bindEvents() {
    window.addEventListener('load', this.onHashChange.bind(this));
    window.addEventListener('hashchange', this.onHashChange.bind(this));
  }
  onHashChange() {
    this.app.current = window.location.hash.slice(1) || '/';
  }

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

  createComponent() {
    // <router-link to="/">fff</router-link>
    Vue.component('router-link', {
      props: {
        to: {
          type: String,
        },
      },
      render(h) {
        return h('a', { attrs: { href: '#' + this.to } }, [
          this.$slots.default,
        ]);
      },
    });

    Vue.component('router-view', {
      render: (h) => {
        // 每次 this.app.current 也就是路由地址的變化,然后就會觸發(fā)此處方法的重新調(diào)用
        const com = this.routerMap[this.app.current];
        console.log(this.app.current);
        return h(com);
      },
    });
  }
}

這部分代碼主要是進(jìn)行Vue的引用以及$router的設(shè)置

VueRouter.install = (_Vue) => {
  // 引用當(dāng)前的vue實(shí)例
  Vue = _Vue;

  Vue.mixin({
    beforeCreate() {
      // 此處的this指向的是 new Vue() 實(shí)例
      if (this.$options.router) {
        // 僅在根組件的時候執(zhí)行以下
        Vue.prototype.$router = this.$options.router;
        // 切記調(diào)用一下此方法,然后進(jìn)行router中的方法初始化操作
        this.$options.router.createInit();
      }
    },
  });
};

外界使用的話,類似原本的 vue-router 的使用

// main.js
import VueRouter from './kRouter/index.js';

Vue.use(VueRouter);

// 注冊路由模塊
const router = new VueRouter({
  routes: [
    { path: '/home', component: Home },
    { path: '/user', component: User },
  ],
});

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

但是此處只是實(shí)現(xiàn)了基本的一些功能,沒有實(shí)現(xiàn)路由嵌套功能,此demo主要是展現(xiàn)其原理,不要在乎那些細(xì)節(jié),希望通過此篇文章,能給學(xué)習(xí) vue-router 的小伙伴提供一些參考和幫助。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容