美文网首页
Vue-router 简单实现

Vue-router 简单实现

作者: Sommouns | 来源:发表于2019-11-11 22:39 被阅读0次
    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') {
          if (!location.hash) {
            location.hash = '/'
          }
          window.addEventListener('load', () => {
            console.log('load')
            this.history.current = location.hash.slice(1)
          })
          window.addEventListener('hashchange', () => {
            console.log('hashchange')
            this.history.current = location.hash.slice(1)
          })
        } else {
          if (location.hash) {
            location.pathname = '/'
          }
          window.addEventListener('load', () => {
            console.log('load')
            this.history.current = location.pathname
          })
          window.addEventListener('popstate', () => {
            console.log('popstate')
            this.history.current = location.pathname
          })
        }
      }
      createMap(routes) {
        return routes.reduce((memo, current) => {
          memo[current.path] = current.component
          return memo
        }, {})
      }
      go() {
    
      }
      push(path) {
        window.history.pushState({}, '', path)
        this.history.current = path
      }
      back() {
    
      }
      afterEach() {
        console.log('after')
      }
      beforeEach() {
    
      }
    }
    VueRouter.install = function (Vue) {
      console.log(Vue, 'install')
    
      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 { // 子节点
            try {
              this._root = this.$parent._root
            } catch (e) {
              console.log(this, e)
            }
          }
          Object.defineProperty(this, '$router', {
            get() {
              return this._root._router
            }
          })
          Object.defineProperty(this, '$route', {
            get() {
              return {
                current: this._root._router.history.current
              }
            }
          })
        }
      })
      Vue.component('router-link', {
        props: {
          to: String,
          tag: String
        },
        render(h) {
          let mode = this._self._root._router.mode
          let tag = this.tag || 'a'
          console.log(this)
          return h(tag, {
            attrs: {
              href: this._self._root._router.mode === 'hash' ? `#${this.to}` : this.to,
            },
            on: {
              click: () => {
                this.handleClick()
              }
            }
          }, this.$slots.default)
        },
        methods: {
          handleClick() {
            this._root._router.push(this.to)
            event.returnValue = false
          }
        }
      })
      Vue.component('router-view', {
        render(h) {
          let current = this._self._root._router.history.current
          let routeMap = this._self._root._router.routesMap
          console.log(this)
    
          return h(routeMap[current])
        }
      })
    }
    export default VueRouter
    
    

    相关文章

      网友评论

          本文标题:Vue-router 简单实现

          本文链接:https://www.haomeiwen.com/subject/lubxictx.html