如果用官方的router就安裝
vue add router
然后選no 哈希模式
main.js
在main.js里先在vue根實例掛載我們的自定義路由實例
import router from './krouter'
new Vue({
el: '#app',
router,
render: h => h(App)
})
krouter.js
當(dāng)Vue.use()執(zhí)行的時候,會走KVueRouter的install方法,在vue的構(gòu)造函數(shù)里面混入我們自定義路由實例,并執(zhí)行了初始化方法,創(chuàng)建KVueRouter實例并傳入配置對象
import Vue from 'vue'
import KVueRouter from './kvue-router'
import Home from './views/Home'
import About from './views/About'
Vue.use(KVueRouter)
export default new KVueRouter({
routes: [
{
path: '/',
name: 'home',
component: Home
},{
path: '/about',
name: 'about',
component: About
}
]
})
kvue-router.js
構(gòu)造函數(shù)保存?zhèn)魅氲呐渲脤ο?br> this.app保存了vue data實例,用來做vue的數(shù)據(jù)響應(yīng)式
bindEvents函數(shù):當(dāng)url哈希值改變和第一次加載時,響應(yīng)式改變當(dāng)前url的哈希值
createRouteMap函數(shù):遍歷routes配置項數(shù)組把里面每一個路由對象作為value 每一個路由對象的path作為key保存在routeMap對象中。
initComponent函數(shù):
創(chuàng)建了router-link組件,實際上a標簽+插槽,用的是h函數(shù)
創(chuàng)建了router-view組件,獲取到routeMap對象中當(dāng)前路徑的對應(yīng)的組件,也是用h函數(shù)創(chuàng)建
let Vue;
//聲明Router類
export default class KVueRouter{
//構(gòu)造函數(shù) 傳入對象
constructor(options){
//1 解析route配置 生成map
//用屬性保存一下變量
this.$options = options;
//聲明一個空對象
this.routeMap = {};
//url響應(yīng)化處理:只要url變化 用到url的組件就會render
//只有把數(shù)據(jù)放在data里面就是響應(yīng)式的
this.app = new Vue({
data : {
current: '/'
}
})
}
//聲明初始化函數(shù)
init(){
//1事件監(jiān)聽
this.bindEvents();
//2路由映射操作
this.createRouteMap();
//3組件聲明和注冊
this.initComponent();
}
//監(jiān)聽hashchange
bindEvents(){
window.addEventListener('hashchange',this.onHashChange.bind(this))
window.addEventListener('load',this.onHashChange.bind(this))
}
onHashChange(){
//url井號后面就是hash
//#/index 只拿井號后面的
this.app.current = window.location.hash.slice('1') || '/'
}
//路由映射
createRouteMap(){
//循環(huán)遍歷路由配置項
this.$options.routes.forEach(item => {
//key是path value是整個路由配置項對象
this.routeMap[item.path] = item;
})
}
initComponent(){
Vue.component('router-link',{
props: {
to: String
},
render(h){
//<a href={this.to}>{this.$slot.default}</a>
//h(tag,data,children)
return h('a',{attrs:{href: '#'+this.to}},[this.$slots.default]);
}
})
Vue.component('router-view',{
render:(h) => {
const component = this.routeMap[this.app.current].component;
return h(component);
}
})
}
}
//實現(xiàn)插件
//插件接收vue構(gòu)造函數(shù)
KVueRouter.install = function (_vue) {
//是Vue的構(gòu)造函數(shù) 用變量保存
Vue = _vue;
//在這一層的this會是誰呢
//混入 進行掛載操作
Vue.mixin({
//傳入一個生命周期函數(shù)
beforeCreate(){
//main.js根組件實例掛載了一次路由器的實例router
//this就是vue實例 === 根組件實例
if(this.$options.router){
//為了拿路由器的實例
Vue.prototype.$router = this.$options.router;
//執(zhí)行初始化
this.$options.router.init();
}
}
})
}
使用
<nav>
<router-link to="/">home</router-link>
<router-link to="/about">about</router-link>
</nav>
<router-view></router-view>