最近在整理菜单相关的业务,对于vueRouter的理解和相关的路由需要有一个更深入的理解。这里写一个简易版的vueRouter帮助理解vueRouter做的事情。
/** * VueRoute的简易实现 */ import Vue from 'vue' class MfRouter{ constructor(options){ this.$options = options this.routeMap = {} // 通过Vue来实现数据的响应式 this.app = new Vue({ data: { current: '/' } }) } /** * 初始化函数 */ init(){ // 绑定事件 this.bindEvents() // 解析路由配置 this.createRouteMap(this.$options) // 初始化内部组件 this.initComponent() } bindEvents(){ window.addEventListener('load', this.onHashChange.bind(this)) window.addEventListener('hashchange', this.onHashChange.bind(this)) } /** * hashchange的相应事件,更细响应式数据 */ onHashChange(){ this.app.current = window.location.hash.slice(1) || '/' } /** * * @param options */ createRouteMap(options){ options.routes.forEach(item => { this.routeMap[item.path] = item.component }) } /** * 初始化router相关的组件 * @returns {*} */ 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 comp = this.routeMap[this.app.current] return h(comp) } }) } } /** * 插件需要提供的注册函数 * @param Vue */ MfRouter.install = (Vue) => { Vue.mixin({ beforeCreate(){ if(this.$options.router){ Vue.prototype.$router = this.$options.router this.$options.router.init() } } }) } /** * Foo Bar 两个路由组件 * @type {{render(*): *}} */ const Foo = { render(h){ return h('div', {}, 'foo') } } const Bar = { render(h){ return h('div', {}, 'bar') } } /** * 容器组件 * @type {{render(*): *}} */ const App = { render(h){ return h('div', {attrs: { id: 'app' }}, [ h('router-link', {attrs: {to: '/foo'}}, 'foo'), h('router-link', {attrs: {to: '/bar'}}, 'bar'), h('router-view') ]) } } /** * 初始化使用 * @type {MfRouter} */ let router = new MfRouter({ routes: [{ path: '/foo', component: Foo }, { path: '/bar', component: Bar }] }) Vue.use(MfRouter) new Vue({ el: '#app', router, render(h){ return h(App) } }) 复制代码