前言
在上一篇 [手撕Vue-Router-新增全域性$router屬性]
中,實現了將每一個 Vue 例項上掛載一個 $router
屬性,這個屬性就是我們在上一篇文章中建立的 VueRouter 例項。
開始
本章節,我們將實現一個 router-link
元件,這個元件可以實現點選跳轉到指定的路由。
實現思路
我們需要實現一個 router-link
元件,這個元件可以實現點選跳轉到指定的路由。
實現 router-link 元件,我們需要注意以下幾點:
- 只要外界使用了Vue-Router, 那麼我們就必須提供兩個自定義的元件給外界使用,一個是
router-link
元件,一個是router-view
元件。 - 只要外界透過Vue.use註冊了Vue-Router, 就代表外界使用了Vue-Router
- 只要外界透過Vue.use註冊了Vue-Router, 就會呼叫外掛的install方法
- 所以我們只需要在install方法中註冊兩個全域性元件給外界使用即可
程式碼實現
- 只要外界使用了Vue-Router, 那麼我們就必須提供兩個自定義的元件給外界使用,一個是
router-link
元件,一個是router-view
元件。首先本章節我們只實現router-link
元件。 - 只要外界透過Vue.use註冊了Vue-Router, 就代表外界使用了Vue-Router
- 只要外界透過Vue.use註冊了Vue-Router, 就會呼叫外掛的install方法
- 所以我們只需要在install方法中註冊兩個全域性元件給外界使用即可
程式碼如下:
NueRouter.install = (Vue, options) => {
...
Vue.component('router-link', {
});
}
好了到此為止,就完成了新增 router-link 元件,只是簡簡單單的新增了一個元件,還沒有實現跳轉的功能。
實現跳轉功能
透過觀察官方的 router-link
元件,我們可以發現,這個元件是一個 <a>
標籤,所以我們可以透過 <a>
標籤的 href
屬性來實現跳轉。
這麼一來,在根據 Vue 官方文件中介紹的元件註冊方式,我們可以在 component 中使用 render 函式來實現渲染 a 標籤。
a 標籤渲染完畢了但是跳轉的地址還沒有,還需要在 component 中新增一個 props 屬性,這個屬性就是我們要跳轉的地址。
總結:透過 render 函式渲染 a 標籤,透過 props 屬性傳遞跳轉地址。
程式碼如下:
Vue.component('router-link', {
props: {
to: {
type: String,
}
},
render() {
return <a href={this.to}></a>
}
});
寫完發現,a 標籤渲染了,但是沒有內容,我們需要在 a 標籤中新增內容,這個內容就是我們在使用 router-link 元件時傳入的內容。
我們可以透過 this.$slots.default
來獲取到我們在使用 router-link 元件時傳入的內容。
程式碼如下:
return <a href={this.to}>{this.$slots.default}</a>
測試自己寫的 router-link 元件,發現可以改變了,發現還有一個問題,就是路由的 mode 為 hash 時,生成的 a 標籤的 href 屬性是 /#/xxx
,如果 mode 為 history 時,生成的 a 標籤的 href 屬性是 /xxx
, 這個問題我們還需要解決。
那麼怎麼獲取到路由的 mode 呢?我們可以透過 this.$router.mode
來獲取到路由的 mode。
這裡有一個注意點:
render 方法中的 this 並不是當前例項物件, 而是一個代理物件, 如果我們想拿到當前例項物件,那麼可以透過
this._self
獲取
知道了這些內容之後,我們就可以透過 this._self.$router.mode
來獲取到路由的 mode 了。根據路由的 mode 來判斷生成的 a 標籤的 href 屬性。
程式碼如下:
render() {
let path = this.to;
if (this._self.$router.mode === 'hash') {
path = '#' + path;
}
return <a href={path}>{this.$slots.default}</a>
}
測試一下,發現可以了。好了,到此為止,我們就完成了 router-link
元件的實現。
最後
大家好我是 BNTang, 一個熱愛分享的技術的開發者,如果大家覺得我的文章對你有幫助的話,可以關注我的公眾號 JavaBoyL
,我會在公眾號中分享一些IT技術和一些個人的見解,謝謝大家的支援。