手撕Vue-Router-新增全域性$router屬性

BNTang發表於2023-11-23

前言

經過上一篇文章的介紹,完成了初始化路由相關資訊的內容,接下來我們需要將路由資訊掛載到Vue例項上,這樣我們就可以在Vue例項中使用路由資訊了。

簡而言之就是給每一個Vue例項新增一個$router屬性,這個屬性就是我們在上一篇文章中建立的VueRouter例項。

實現思路

我們需要在Vue例項建立之前,將VueRouter例項掛載到Vue例項上,這樣我們就可以在Vue例項中使用$router屬性了。

在我們實現的 NueRouter 時,我們透過 Vue.use 來安裝好我們的路由外掛,那麼在編寫外掛中有一個 install 方法,這個方法會在 Vue.use 時被呼叫,我們可以在這個方法中將 VueRouter 例項掛載到 Vue 例項上。

在 Vue 中有一個 mixin 方法,這個方法會在每個元件建立之前被呼叫,我們可以在這個方法中將 VueRouter 例項掛載到 Vue 例項上。

重寫 beforeCreate 方法,將 VueRouter 例項掛載到 Vue 例項上。在 beforeCreate 方法中,我們可以透過 this.$options.router 獲取到我們在 new Vue 時傳入的 router 物件,然後將這個物件掛載到 Vue 例項上。如果透過 this.$options.router 獲取到了 router 物件,那麼就說明這個 Vue 例項是根例項,我們就可以將 router 物件掛載到 Vue 例項上了。

如果獲取不到 router 物件,那麼就說明這個 Vue 例項不是根例項,我們就需要將父元件的 router 物件掛載到 Vue 例項上。

大致思路就是這樣,接下來我們來實現一下。

程式碼實現

NueRouter.install = (Vue, options) => {
    Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.router) {
                this.$router = this.$options.router;
                this.$route = this.$router.routerInfo;
            } else {
                this.$router = this.$parent.$router;
                this.$route = this.$router.routerInfo;
            }
        }
    })
}

如上的程式碼就是我們實現的思路,我們透過 this.$options.router 獲取到我們在 new Vue 時傳入的 router 物件,然後將這個物件掛載到 Vue 例項上。如果獲取不到 router 物件,那麼就說明這個 Vue 例項不是根例項,我們就需要將父元件的 router 物件掛載到 Vue 例項上。

測試

接下來就是我們平時要進行的測試了,分別在各個元件當中列印一下 $router$route 屬性,看看是否掛載成功。

App.vue:

mounted() {
    console.log("App", this.$router);
    console.log("App", this.$route);
}

Home.vue:

mounted() {
    console.log("Home", this.$router);
    console.log("Home", this.$route);
}

About.vue:

mounted() {
    console.log("About", this.$router);
    console.log("About", this.$route);
}

最後我們來看一下效果:

可以看到我們的路由資訊已經掛載到 Vue 例項上了。

最後

到這裡我們就完成了將路由資訊掛載到 Vue 例項上的功能,接下來下一篇文章我會帶著大家來實現 實現router-link

相關文章