手写一个基础的VueRouter构造函数

本文将逐步介绍如何手写一个基础的VueRouter构造函数,涵盖核心的路由配置、导航守卫、组件懒加载等功能,帮助你深入理解Vue.js路由原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

let _vue = null
export default class VueRouter {
  static install (Vue) {
    // 判断当前插件是否已经安装
    if (VueRouter.install.installed) {
      return
    }
    VueRouter.install.installed = true
    // vue记录到全局变量
    _vue = Vue
    // 创建vue实例时,把传入的routes对象注入到vue实例上
    // 混入,this指向的vue实例
    _vue.mixin({
      beforeCreate () {
        if (this.$options.router) {
          _vue.prototype.$router = this.$options.router
          this.$options.router.init()
        }
      }
    })
  }

  constructor (options) {
    // 创建的时候传进来的路由参数
    this.options = options
    // 路由-组件的键值对
    this.routemap = {}
    // 保存当前的路由,一个响应式的数据
    this.data = _vue.observable({
      current: '/'
    })
  }

  // 根据传入的options即路由规则,得到路由-组件的键值对,存在routeMap
  createRouteMap () {
    // 我们配置的路由规则
    const { routes } = this.options
    routes.forEach(route => {
      this.routemap[route.path] = route.component
    })
  }

  initComponents (Vue) {
    // 创建router-link组件
    Vue.component('router-link', {
      props: {
        to: String
      },
      // 运行时,不支持template属性
      // template: '<a :href="to"><slot></slot></a>'
      // 可以写render函数替代,或者配置runtimeCompiler:true
      render (h) {
        return h('a', {
          attrs: { href: this.to },
          on: {
            click: this.clickHandler
          }
        }, [this.$slots.default])
      },
      methods: {
        clickHandler (e) {
          // 改变浏览器地址栏
          history.pushState({}, '', this.to)
          // 响应的路由更新,便于获取对应的组件,并加载
          this.$router.data.current = this.to
          // 阻止a标签点击后自动调服务
          e.preventDefault()
        }
      }
    })

    const self = this
    Vue.component('router-view', {
      render (h) {
        const component = self.routemap[self.data.current]
        return h(component)
      }
    })
  }

  init () {
    this.createRouteMap()
    this.initComponents(_vue)
    this.initEvent()
  }

  // 解决后退或者前进的时候,加载对应的组件
  initEvent () {
    window.addEventListener('popstate', () => {
      this.data.current = window.location.pathname
    })
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值