如何在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響應式原理的博文请敦!