main.js中
import Vue from "vue"; import App from "./App.vue"; import router from './krouter' Vue.config.productionTip = false; Vue.prototype.$bus = new Vue(); new Vue({ router, render: h => h(App) }).$mount("#app");
kvue-router.js 文件 ---> 插件实现
let Vue; class VueRouter { constructor(options) { this.$options = options // 创建一个路由的path和route映射 this.routeMap = {} // 将来当前路径current需要响应式 // 利用Vue的响应式原理可以做到这一点 this.app = new Vue({ data: { current: '/' } }) } init(){ // 绑定浏览器事件 this.bindEvents() // 解析路由配置 this.createRouteMap(this.$options) // 创建router-link 和 router-view this.initComponent() } bindEvents() { window.addEventListener('hashchange', this.onHashChange.bind(this)) window.addEventListener('load', this.onHashChange.bind(this)) } onHashChange() { // http://localhost/#/home slice(1)可以把#去掉,拿后面的部分 this.app.current = window.location.hash.slice(1) || '/' } createRouteMap(options){ options.routes.forEach(item => { // ['/home']: {path: '/home', component: Home} this.routeMap[item.path] = item }) } 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) // jsx写法 // 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变为插件 VueRouter.install = function(_Vue) { Vue = _Vue // 这里保存,上面使用 // 混入任务 Vue.mixin({ // 混入就是扩展Vue beforeCreate() { // 这里的代码将来会再外面初始化的时候被调用 // 这样外面就实现了Vue扩展 // 这里的this就是Vue实例 // 但是这里会在所有组件的创建过程中都执行,所以这里不健壮 // Vue.prototype.$router = this.$options.router // 这里只希望根组件执行一次 if(this.$options.router){ Vue.prototype.$router = this.$options.router // 路由进行初始化 this.$options.router.init() } } }) } export default VueRouter
krouter.js ---> 相当于router.js
import Vue from 'vue' import VueRouter from './kvue-router' import About from './views/About.vue' import Home from './views/Home.vue' // 插件注册 Vue.use(VueRouter) export default new VueRouter({ routes: [ {path: "/", component: Home}, {path: "/about", component: About} ] })