Vue-Router
hash模式
- URL中#号前面的内容作为门路地址
- 监听hashchange事件
- 依据以后路与地址找到对应的组件从新渲染
history模式 - 通过history.pushState()办法扭转地址栏
- 监听popstate事件
- 依据以后路由地址找到对应组件从新渲染
根本应用
// 1. 注册路由插件Vue.use(VueRouter)// 2. 创立 router 对象const router = new VueRouter({ routes:[ {nmae:'home',path:'/',component:homeComponent} ]})const vm = new Vue({ // 3. 注册 router 对象 router, render: h => h(App)}).$mount('#app')
第一步实现install办法
第二步实现构造函数,构造函数中须要初始化options,data,routeMap三个属性,data为响应式对象
第三步,实现createRouteMap办法,把构造函数中传入options中的routes结构成键值对存储到routeMap中,键为路由地址,值为对于组件。
第四步,实现initComponents办法
第五步,运行时版本vue不反对template模板,手动实现一个render函数
第六步,实现initEvent()办法
/* eslint-disable indent */let _Vueexport default class VueRouter { // 先实现install办法 // 1,判断以后插件是否曾经装置 static install (Vue) { if (VueRouter.install.installed) { return } VueRouter.install.installed = true // 2,把Vue构造函数记录到全局变量 _Vue = Vue // 3,把创立Vue实例传入的router对象注入到Vue实例上 // 混入 _Vue.mixin({ beforeCreate () { if (this.$options.router) { // 只需执行一次,并且是vue实例才执行,组件选项中没有router属性 _Vue.prototype.$router = this.$options.router // this.$options.router.init() // 调用初始化两个办法 } } }) } // 第二步实现构造函数 constructor (options) { this.options = options this.routeMap = {} // 解析options存储的routes,键是路由地址,值是组件 this.data = _Vue.observable({ current: '/' }) this.init() } // 第三步实现createROuteMap createRouteMap () { // 遍历所有路由规定,把路由规定解析成键值对的模式 存储到routeMap中 this.options.routes.forEach(route => { this.routeMap[route.path] = route.component }) } init () { this.createRouteMap() this.initComponents(_Vue) this.initEvent() } initComponents (Vue) { // 实现一个router-link组件 Vue.component('router-link', { props: { to: String }, // template: '<a :href="to"><slot></slot></a>' 运行时版本vue不反对template模板 render (h) { return h('a', { attrs: { href: this.to }, on: { click: this.clickHandler // 阻止点击的默认行为 } }, [this.$slots.default]) }, methods: { clickHandler (e) { history.pushState({}, '', this.to) // 扭转以后路由地址 this.$router.data.current = this.to e.preventDefault() } } }) const self = this Vue.component('router-view', { render (h) { const component = self.routeMap[self.data.current] return h(component) // 转化component为虚构dom } }) } initEvent () { // 注册popstate事件 window.addEventListener('popstate', () => { // this代表组件实例 this.data.current = window.location.pathname }) }}