简易的VueRouter实现

Vue Router

Vue Router是VueJS官方的路由管理器。它和VueJS的核心深度集成,让构建单页面应用变得易如反掌

基于Hash模式的路由实现

kRouter.js

import Vue from 'vue'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

class VueRouter {
  constructor (options) {
    this.$options = options
    this.routeMap = {}
    // 引用Vue中数据的响应式  当路由发生改变重新去渲染页面
    this.app = new Vue({
      data: {
        current: '/'
      }
    })
  }

  init () {
    // 监听URL的变化
    this.bindEvents()
    // 解析路由配置
    this.createRouteMap(this.$options)
    //  实现两个组件
    this.initComponent()
  }

  bindEvents () {
    window.addEventListener('load', this.onHashChange.bind(this))
    window.addEventListener('hashchange', this.onHashChange.bind(this))
  }

  onHashChange () {
    // console.log(window.location.hash)  #/home
    this.app.current = window.location.hash.slice(1) || '/'
  }

  createRouteMap (options) {
    options.routes.forEach(item => {
    // {'/':Home,'/about':About}
      this.routeMap[item.path] = item.component
    })
  }

  initComponent () {
    // <router-link>home</router-link>
    Vue.component('router-link', {
      props: { to: String },
      render (h) {
      	// this.$slots.default 存储了当前元素的子节点
        return h('a', { attrs: { href: '#' + this.to } }, [
          this.$slots.default
        ])
      }
    })
    // router-view
    Vue.component('router-view', {
      render: h => {
        const comp = this.routeMap[this.app.current]
        return h(comp)
      }
    })
  }
}
// 入参是Vue构造函数
VueRouter.install = function (Vue) {
  // 混入
  Vue.mixin({
    beforeCreate () {
      // this.$options 表示new VUe({})实例中的配置项
      // this 是 当前的Vue实例
      if (this.$options.router) {
        // 仅在根组件中执行一次
        // 后面的组件中都可以使用this.$router
        Vue.prototype.$router = this.$options.router
        this.$options.router.init()
      }
    }
  })
}

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]

const router = new VueRouter({
  routes
})

export default router

1、在创建VueRouter类的时候,需要去实现install方法使用VueRouter作为VueJS的插件来使用。VueRouter作为插件加入使用,通过mixin混入来影响每一个Vue实例化,在beforeCreate钩子的时候就会完成router的初始化,并且只初始化一次。
2、在VueRouter中有三个核心的方法

  • 监听URL变化
    通过监听URL的变化,去找到对应的组件渲染
  • 解析路由配置
    将URL与组件映射成一个对象
  • 构建两个组件
    渲染组件(view-router)页面跳转组件(view-link)
    3、render渲染函数

简单的说,在Vue中我们使用模板HTML语法来组建页面,使用render函数我们可以用js语言来构建DOM。因为Vue是虚拟DOM,所以在拿到template模板时也要转译成vNode的函数,而用render函数构建的DOM,Vue就免去了转译过程

render: h => {	
        const comp = this.routeMap[this.app.current]
        return h(comp)
      }

这里我们将路由匹配的组件,通过render函数渲染成VNode。

基于HTML5History模式

import Vue from 'vue'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

class VueRouter {
  constructor (options) {
    this.$options = options
    this.routeMap = {}
    // 引用Vue中数据的响应式  当路由发生改变重新去渲染页面
    this.app = new Vue({
      data: {
        current: '/'
      }
    })
  }

  init () {
    // 监听URL的变化
    this.bindEvents()
    // 解析路由配置
    this.createRouteMap(this.$options)
    //  实现两个组件
    this.initComponent()
  }

  bindEvents () {
    window.addEventListener('load', this.onHashChange.bind(this))
    window.addEventListener('hashchange', this.onHashChange.bind(this))
  }

  onHashChange () {
    this.app.current = window.location.pathname || '/'
  }

  createRouteMap (options) {
    options.routes.forEach(item => {
    // {'/':Home,'/about':About}
      this.routeMap[item.path] = item.component
    })
  }

  initComponent () {
    // <router-link>home</router-link>
    Vue.component('router-link', {
      props: { to: String },
      render (h) {
        return h('a', { attrs: { href: this.to } }, [
          this.$slots.default
        ])
      }
    })
    // router-view
    Vue.component('router-view', {
      render: h => {
        const comp = this.routeMap[this.app.current]
        return h(comp)
      }
    })
  }
}
// 入参是Vue构造函数
VueRouter.install = function (Vue) {
  // 混入
  Vue.mixin({
    beforeCreate () {
      // this.$options 表示new VUe({})实例中的配置项
      // this 是 当前的Vue实例
      if (this.$options.router) {
        // 仅在根组件中执行一次
        // 后面的组件中都可以使用this.$router
        Vue.prototype.$router = this.$options.router
        this.$options.router.init()
      }
    }
  })
}

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]

const router = new VueRouter({
  routes
})

export default router

效果图

在这里插入图片描述

发布了17 篇原创文章 · 获赞 0 · 访问量 394

猜你喜欢

转载自blog.csdn.net/k19970320j/article/details/104456940
今日推荐