1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| let Vue = null; class HistoryRoute { constructor(){ this.current = null } } class VueRouter{ constructor(options) { this.mode = options.mode || "hash" this.routes = options.routes || [] this.routesMap = this.createMap(this.routes) this.history = new HistoryRoute(); this.init()
} init(){ if (this.mode === "hash"){ location.hash? '':location.hash = "/"; window.addEventListener("load",()=>{ this.history.current = location.hash.slice(1) }) window.addEventListener("hashchange",()=>{ this.history.current = location.hash.slice(1) }) } else{ location.pathname? '':location.pathname = "/"; window.addEventListener('load',()=>{ this.history.current = location.pathname }) window.addEventListener("popstate",()=>{ this.history.current = location.pathname }) } }
createMap(routes){ return routes.reduce((pre,current)=>{ pre[current.path] = current.component return pre; },{}) }
} VueRouter.install = function (v) { Vue = v; Vue.mixin({ beforeCreate(){ if (this.$options && this.$options.router){ this._root = this; this._router = this.$options.router; Vue.util.defineReactive(this,"xxx",this._router.history) }else { this._root= this.$parent && this.$parent._root } Object.defineProperty(this,'$router',{ get(){ return this._root._router } }); Object.defineProperty(this,'$route',{ get(){ return this._root._router.history.current } }) } }) Vue.component('router-link',{ props:{ to:String }, render(h){ let mode = this._self._root._router.mode; let to = mode === "hash"?"#"+this.to:this.to return h('a',{attrs:{href:to}},this.$slots.default) } }) Vue.component('router-view',{ render(h){ let current = this._self._root._router.history.current let routeMap = this._self._root._router.routesMap; return h(routeMap[current]) } }) };
export default VueRouter
|