Vue-Router核心實現(xiàn)原理

如何在vue中使用vue-router?

1.Vue使用插件质和,即調用Vue的use方法;

// router.js 
Vue.use(Router);

2.實例化router稚字,并配置router的配置對象饲宿,含routes路由厦酬;

// router.js 
export default new Router({
    mode:"hash",
    routes:[
        {
            path:"/hello",
            component:HelloWorld
        },
        {
            path:"/",
            component:VuexTest
        },
        {
            path:"/form",
            component:Form
        }
    ]
})

3.在vue實例上配置router實例;

// main.js
import router from "./config/router";
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

4.使用

<template>
  <div id="app">
    <router-link to="/">home</router-link>|
    <router-link to="/form">form</router-link>|
    <router-link to="/hello">HelloWorld</router-link>
    <router-view></router-view>
  </div>
</template>

5.效果

點擊home瘫想,form仗阅,helloWorld可以切換路由頁面。

以上的幾個步驟国夜,vue-router內部都做了什么减噪?

我們需要明白的是,router-link和router-view是兩個Vue全局組件,必定是在vue-router中實現(xiàn)了全局定義兩個組件车吹,他們分別用來跳轉路由和展示路由對應的組件內容旋廷。

我們點擊了router-link時導致路由變了,vue-router內部必然是在監(jiān)聽路由變化礼搁,根據(jù)路由規(guī)則找到匹配的組件饶碘,然后在router-view中渲染。

所以馒吴,路由切換最終是頁面的不同組件的展示扎运,而沒有真正去刷新頁面。

那么接下來說vue-router核心實現(xiàn)原理:

目標:
1.實現(xiàn)一個靜態(tài)install方法饮戳,因為作為插件都必須有這個方法豪治,給Vue.use()去調用;
2.可以監(jiān)聽路由變化扯罐;
3.解析配置的路由负拟,即解析router的配置項routes,能根據(jù)路由匹配到對應組件歹河;
4.實現(xiàn)兩個全局組件router-link和router-view掩浙;(最終落地點)

核心代碼實現(xiàn)簡版:

let Vue;
class KVueRouter {
    constructor(options){
        this.$options=options;
        this.$routerMap={};//{"/":{component:...}}
        // url 響應式,當值變化時引用的地方都會刷新
        this.app = new Vue({
            data:{
                current:"/"
            }
        });
    }
    // 初始化
    init(){
        // 監(jiān)聽事件
        this.bindEvent();
        // 解析路由
        this.createRouteMap();
        // 聲明組件
        this.initComponent();
    }
    bindEvent(){
        window.addEventListener('hashchange',this.onHashchange.bind(this));
    }
    onHashchange(){
        this.app.current = window.location.hash.slice(1) || "/";
    }
    createRouteMap(){
        this.$options.routes.forEach(route=>{
            this.$routerMap[route.path]=route;
        })
    }
    initComponent(){
        Vue.component('router-link',{
            props:{
                to:String,
            },
            render(h){
                return h('a',{attrs:{href:'#'+this.to}},[this.$slots.default])
            }
        });
        Vue.component('router-view',{
            render:(h)=>{
                const Component = this.$routerMap[this.app.current].component;
                return h(Component)
            }
        });
    }
}
// 參數(shù)是vue構造函數(shù)秸歧,Vue.use(router)時,執(zhí)行router的install方法并把Vue作為參數(shù)傳入
KVueRouter.install = function(_vue){
    Vue = _vue;
    //全局混入
    Vue.mixin({
        beforeCreate(){//拿到router的示例厨姚,掛載到vue的原型上
            if (this.$options.router) {
                Vue.prototype.$router=this.$options.router;
                this.$options.router.init();
            }
        }
    })
}
export default KVueRouter;

解讀如下:

  • Vue.use(Router)時,會調用router的install方法并把Vue類傳入键菱,混入beforeCreate方法谬墙,即在Vue實例化后掛載前在vue原型上掛個$router方法(因為這樣后面才能用this.$router.push()...但此處沒有實現(xiàn)哦),然后調用router實例的init方法经备;

  • 在init中把三件事情都干了拭抬,監(jiān)聽路由,解析路由(路由mapping匹配)侵蒙,定義組件造虎;

  • 需要注意的是,存儲當前路由的變量this.app.current非一般的變量蘑志,而是借用Vue的響應式定義的累奈,所以當路由變化時只需要給這個this.app.current賦值贬派,而router-view組件剛好引用到這個值,當其改變時所有的引用到的地方都會改變澎媒,則得到的要展示的組件也就響應式的變化了搞乏。

而vue實例data下的屬性為什么會是響應式的?如何實現(xiàn)的戒努?請關注后續(xù)vue響應式原理的博文请敦!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市储玫,隨后出現(xiàn)的幾起案子侍筛,更是在濱河造成了極大的恐慌,老刑警劉巖撒穷,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匣椰,死亡現(xiàn)場離奇詭異,居然都是意外死亡端礼,警方通過查閱死者的電腦和手機禽笑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛤奥,“玉大人佳镜,你說我怎么就攤上這事》睬牛” “怎么了蟀伸?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缅刽。 經(jīng)常有香客問我啊掏,道長,這世上最難降的妖魔是什么拷恨? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任脖律,我火速辦了婚禮谢肾,結果婚禮上腕侄,老公的妹妹穿的比我還像新娘。我一直安慰自己芦疏,他們只是感情好冕杠,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著酸茴,像睡著了一般分预。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上薪捍,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天笼痹,我揣著相機與錄音配喳,去河邊找鬼。 笑死凳干,一個胖子當著我的面吹牛晴裹,可吹牛的內容都是我干的。 我是一名探鬼主播救赐,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼涧团,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了经磅?” 一聲冷哼從身側響起泌绣,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎预厌,沒想到半個月后阿迈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡轧叽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年仿滔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犹芹。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡崎页,死狀恐怖,靈堂內的尸體忽然破棺而出腰埂,到底是詐尸還是另有隱情飒焦,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布屿笼,位于F島的核電站牺荠,受9級特大地震影響,放射性物質發(fā)生泄漏驴一。R本人自食惡果不足惜休雌,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肝断。 院中可真熱鬧杈曲,春花似錦、人聲如沸胸懈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽趣钱。三九已至涌献,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間首有,已是汗流浹背燕垃。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工枢劝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卜壕。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓呈野,卻偏偏與公主長得像,于是被迫代替她去往敵國和親印叁。 傳聞我的和親對象是個殘疾皇子被冒,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內容

  • 路由,其實就是指向的意思轮蜕,當我點擊頁面上的home按鈕時昨悼,頁面中就要顯示home的內容,如果點擊頁面上的about...
    六月太陽花閱讀 580評論 0 3
  • 回憶: 我們知道跃洛,h5的history或者hash幫助我們解決了率触,變化url跳轉頁面不發(fā)送請求,并且我們能監(jiān)聽到u...
    LoveBugs_King閱讀 3,648評論 0 5
  • SPA單頁應用 傳統(tǒng)的項目大多使用多頁面結構两曼,需要切換內容的時候我們往往會進行單個html文件的跳轉,這個時候受網(wǎng)...
    視覺派Pie閱讀 11,844評論 1 55
  • PS:轉載請注明出處作者: TigerChain地址http://www.reibang.com/p/9a7d7...
    TigerChain閱讀 63,731評論 9 218
  • 那這次呢?我決定直接就先放一個小小demo上來 其實我們在引入vue-router插件那一刻,我們的網(wǎng)頁就已經(jīng)附帶...
    看物看霧閱讀 825評論 0 1