手写vue-router

限于喜欢 提交于 2020-02-01 22:01:06

hash模式:location.hash: 获取url的hash值; window.onhashchange监听hash的改变

history模式:location.pathname:获取路径; window.onpopstate监听history变化

vue.use的用法

把你给它的东西调用一遍;如果你给它的是一个方法,那么它会直接执行这个方法,如果你给它的东西里有一个install属性,它会执行这个install

function a () {
  console.log('This is function a')
}
a.install = function (vue) {
  console.log('add "install" property to function a')
  // 全局混入vue实例,添加在mixin中的的变量,方法在所有子组件中都可以被获取到
  vue.mixin({
    data () {
      return {
        c: 'this is in mixin'
      }
    },
    methods: {
      testMethod () {
      }
    },
    // 生命周期注入
    created () {
      console.log('I\'m in global created method')
    }
  })
}
Vue.use(a)
// add "install" property to function a

实现自己的vue-router

class HistoryRouter {
  constructor () {
    this.current = null
  }
}

class vueRouter {
  constructor (option) {
    this.mode = option.mode || 'history'
    this.routes = option.routes || []
    this.history = new HistoryRouter()
    this.routesMap = this.createMap(this.routes)
    this.init()
  }

  init () {
    if (this.mode === 'hash') {
      location.hash ? '' : location.hash = '/'
      window.addEventListener('load', () => {
        // 初始化history.current
        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('hashchange', () => {
        this.history.current = location.pathname
      })
    }
  }

  createMap (routes) {
    return routes.reduce((memo, current) => {
      memo[current.path] = current.component
      return memo
    })
  }
}

vueRouter.install = function (vue) {
  vue.mixin({
    beforeCreate () {
      // $options指创建vue实例时传入的参数
      if (this.$options && this.$options.router) {
        this._root = this
        this._router = this.$options.router
        vue.util.defineReactive(this, 'current', this._router.history)
      } else {
        this._root = this.$parent._root
      }
    }
  })
  // 创建组件
  vue.component('router-view', {
    render (h) {
      let current = this._self._root._router.history.current
      let routesMap = this._self._root._router.routesMap
      console.log('current: ', current)
      return h(routesMap[current])
    }
  })
}

export default vueRouter

vue.util.defineReactive与vue中双向绑定实现原理相同,可以通过该api实现监听第三方变量

vue.util.extend实际就是一个对象拷贝方法;

vue.extend在任何地方可以拿到任何一个组件

const Constructor = Vue.extend(HelloWorld)
const vm = new Constructor().$mount()
// vm就是helloworld这个组件

 

const Constructor = Vue.extend(HelloWorld)

const vm = new Constructor().$mount()

// vm就是helloworld这

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!