Vue-Router原理简单实现 Posted on 2022-02-13 | In vue Vue-Router原理简单实现 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394// 保存 Vue 的局部变量let _Vue = nullexport default class VueRouter { static install (Vue) { // 判断当前插件是否已经被安装 if (VueRouter.install.installed) return VueRouter.install.installed = true // 把Vue的构造函数记录到全局变量 _Vue = Vue // 把创建Vue实例时候传入的router对象注入到Vue实例上 // 将每个组件都混入 beforeCreate _Vue.mixin({ beforeCreate () { if (this.$options.router) { _Vue.prototype.$router = this.$options.router this.$options.router.init() } } }) } constructor (options) { // 传入的路由数据 this.options = options // 存储路由 this.routeMap = {} // path需要监听到可变的 this.data = _Vue.observable({ current: '/' }) } init () { this.createRouteMap() this.initComponent(_Vue) this.initEvent() } createRouteMap () { // 遍历所有的路由规则,把路由规则解析成键值对 this.options.routes.forEach(route => { this.routeMap[route.path] = route.component }) } // router-link的实现,a标签的超链接 initComponent (Vue) { Vue.component('router-link', { props: { to: { type: String } }, render (h) { return h('a', { attrs: { href: this.to }, on: { click: this.clickHandler } }, [this.$slots.default]) }, methods: { // 点击router-link, 加载对应的组件 clickHandler (e) { history.pushState({}, '', this.to) this.$router.data.current = this.to e.preventDefault() } } // template: '<a :href="to"><slot></slot></a>' }) const self = this Vue.component('router-view', { render (h) { const component = self.routeMap[self.data.current] return h(component) } }) } // 处理浏览器前进后退重新加载视图 initEvent () { window.addEventListener('popstate', () => { this.data.current = window.location.pathname }) }}