1. 目錄結構
2.實現vue-router源碼
// kvue-router.js
/* eslint-disable */ // 禁止eslint
let Vue;
class VueRouter {
constructor(options){ // router傳入參數
this.$options = options;
this.routeMap = {}; // 所有的routes組件實例
this.app = new Vue({ // 獲取當前的vue
data: {
current: '/'
}
})
}
// vue-router初始化 任務
init() {
this.bindEvents();
this.createRouteMap(this.$options);
this.initComponent()
}
// 全局添加默認綁定任務
bindEvents() {
window.addEventListener('load',this.onHashChange.bind(this),false);
window.addEventListener('hashchange',this.onHashChange.bind(this),false);
}
// 獲取hash地址
onHashChange() {
this.app.current = window.location.hash.slice(1) || '/';
}
// 獲取路由配置裏面的地址
createRouteMap(options) {
options.routes.forEach(item => {
this.routeMap[item.path] = item;
})
}
// 初始化默認router標籤
initComponent() {
// 聲明兩個全局組件
Vue.component('router-link', {
props: {
to: String
},
render(h) {
// 目標是:<a :href="to">xxx</a>
return h('a', {attrs:{href: '#'+this.to}}, this.$slots.default)
// return <a href={this.to}>{this.$slots.default}</a>
}
});
// hash -> current -> render
Vue.component('router-view', {
// 箭頭函數能保留this指向,這裏指向VueRouter實例
render: (h) => {
const Comp = this.routeMap[this.app.current].component;
return h(Comp);
}
})
}
}
// 插件邏輯
VueRouter.install = function(_vue){
Vue = _vue;
Vue.mixin({
beforeCreate() {
if(this.$options.router){
// Vue.prototype.$router = this.$options.router; // 原型鏈上添加router屬性
this.$options.router.init() // 調用vue插件中的init方法
}
},
})
}
export default VueRouter
3.路由配置頁面引入kvue-router.js
// router.js
import Vue from 'vue' // 引入vue
import Router from './kvue-router' // 引入kvue-router
// 使用自定義router插件
Vue.use(Router)
// 實例化vue對象
const router = new Router({
mode: 'hash',
routes: [
{
path:'/home',
title: 'home',
component: () => import('./components/base/home.vue')
},
{
path:'/list',
title: 'list',
component: () => import('./components/base/list.vue')
},
]
})
export default router
4.main.js頁面引入router文件,並且掛載到Vue上
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = true
new Vue({
render: h => h(App),
router
}).$mount('#app')
5.app.vue文件顯示router標籤
// app.vue
<template>
<div id="app">
<router-link to="/home">這是跳到home</router-link><br>
<router-link to="/list">這是跳到list</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
name: ''
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
6.頁面顯示