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 90 91 92 93 94 95
| class HistoryRoute { constructor(){ this.current = null; } }; /** * options: newRouter时传入的参数; */ class VueRouter{ constructor(options){ this.mode = options.mode || 'hash'; this.routes= options.routes || []; // 此处可以直接令this.history.current = null;但是为了记录前后路由跳转历史,生成HistoryRoute类 this.history = new HistoryRoute; this.routesMap = this.creatMap(this.routes); this.init(); //初始化路由 }, init () { // 触发监听事件 // 改变vue-router中的current变量 if (this.mode == 'hash') { // 根据hash的值自动在url上增加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 { // 根据hash的值自动在url上增加hash location.pathname ? '': location.pathname = '/'; window.addEventListener('load',() => { this.history.current = location.pathname; }) window.addEventListener('hashchange',() => { this.history.current = location.pathname; }) } } creatMap(routes){ // 将routes转化成键值对形式 ‘/’: Hello // reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。 // 参数一:初始值, 或者计算结束后的返回值。 // 参数二:当前元素 return routes.reduce((memo, current)=> { memo[current.path] = current.component; return memo }) } } VueRouter.install = function (Vue) { // 监视current变量的监视者 Vue.mixin({ //mixin会注入到每个组件 // 查找到在根实例上放入的VueRouter对象,然后注入到每个组件。 beforeCreate() { // this.$option && this.$options.router:当前这个组件的配置&& 当前组件上已经加载过route路由对象 if (this.$options && this.$options.router) { // 将当前的实例,挂在到当前实例的_root变量上。 this._root = this; // 将当前router 注入到当前实例(组件)的_router上。 this._router = this.$options.router; // 在当前组件this下面中的this._router.history变量上对current进行监听 Vue.util.defineReactive(this,'current', this._router.history); } else { // 逐级向上查找是否挂载 this._root = this.$parent._root; }
// 扩展知识 组件使用this.$router和this.$route // 在this上注册$router属性,并且不能更改。 Object.defineProperty(this, '$router', { get () { return this._root._router; }, }) Object.defineProperty(this, '$route', { get () { return this._root._router.history.current; }, }) } }); Vue.component('route-view', { render(h){ // 根据当前current获取到对应的路径; // _self是vue自带的,_self指向实例自身; let current = this._self._root._router.history.current; let routeMap = this._self._root._router.routesMap; return h(routeMap[current]) //h:渲染作用 } }) } // 暴露vue类 export default VueRouter;
|