当前位置:首页 > VUE

自己实现vue-router

2026-01-20 08:15:54VUE

实现基本路由功能

创建一个简单的路由系统需要定义路由映射和监听URL变化。以下是一个基础实现:

class VueRouter {
  constructor(options) {
    this.routes = options.routes || []
    this.mode = options.mode || 'hash'
    this.current = window.location.hash.slice(1) || '/'
    this.routeMap = this.createMap(this.routes)

    window.addEventListener('load', () => {
      if (!window.location.hash) {
        window.location.hash = '/'
      }
    })

    window.addEventListener('hashchange', () => {
      this.current = window.location.hash.slice(1)
    })
  }

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

实现路由视图组件

创建<router-view>组件用于显示匹配的组件内容:

Vue.component('router-view', {
  render(h) {
    const current = this.$router.current
    const routeComponent = this.$router.routeMap[current]
    return h(routeComponent)
  }
})

实现路由链接组件

创建<router-link>组件用于导航:

Vue.component('router-link', {
  props: {
    to: String
  },
  render(h) {
    return h('a', {
      attrs: {
        href: '#' + this.to
      }
    }, this.$slots.default)
  }
})

安装路由插件

将路由器实例注入Vue原型:

let _Vue
VueRouter.install = function(Vue) {
  _Vue = Vue

  Vue.mixin({
    beforeCreate() {
      if (this.$options.router) {
        Vue.prototype.$router = this.$options.router
      }
    }
  })
}

实现嵌套路由

支持嵌套路由需要递归匹配路径:

function createRouteMap(routes, pathMap = {}, parentPath = '') {
  routes.forEach(route => {
    const normalizedPath = parentPath + route.path
    pathMap[normalizedPath] = route.component

    if (route.children) {
      createRouteMap(route.children, pathMap, normalizedPath)
    }
  })
  return pathMap
}

实现动态路由

支持动态路径参数:

function createRouteMap(routes) {
  const pathList = []
  const pathMap = {}

  routes.forEach(route => {
    addRouteRecord(pathList, pathMap, route)
  })

  return {
    pathList,
    pathMap
  }
}

function addRouteRecord(pathList, pathMap, route, parent) {
  const path = parent ? `${parent.path}/${route.path}` : route.path
  const record = {
    path,
    component: route.component,
    parent
  }

  if (!pathMap[path]) {
    pathList.push(path)
    pathMap[path] = record
  }

  if (route.children) {
    route.children.forEach(child => {
      addRouteRecord(pathList, pathMap, child, record)
    })
  }
}

实现导航守卫

添加全局前置守卫功能:

class VueRouter {
  constructor(options) {
    this.beforeHooks = []
  }

  beforeEach(fn) {
    this.beforeHooks.push(fn)
  }

  navigateTo(path) {
    const hooks = this.beforeHooks
    const from = this.current
    const to = path

    runQueue(hooks, from, to, () => {
      this.current = to
      window.location.hash = to
    })
  }
}

function runQueue(queue, from, to, cb) {
  function next(index) {
    if (index >= queue.length) return cb()
    const hook = queue[index]
    hook(from, to, () => {
      next(index + 1)
    })
  }
  next(0)
}

实现HTML5历史模式

支持history API的路由模式:

class VueRouter {
  constructor(options) {
    this.mode = options.mode || 'hash'

    if (this.mode === 'history') {
      this.current = window.location.pathname
      window.addEventListener('popstate', () => {
        this.current = window.location.pathname
      })
    } else {
      // hash模式实现
    }
  }

  push(path) {
    if (this.mode === 'history') {
      window.history.pushState({}, '', path)
      this.current = path
    } else {
      window.location.hash = path
    }
  }
}

完整使用示例

将各部分组合后的使用方式:

const router = new VueRouter({
  mode: 'hash',
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
    { 
      path: '/user', 
      component: User,
      children: [
        { path: 'profile', component: Profile }
      ]
    }
  ]
})

router.beforeEach((from, to, next) => {
  console.log(`Navigating from ${from} to ${to}`)
  next()
})

new Vue({
  router,
  el: '#app'
})

自己实现vue-router

标签: vuerouter
分享给朋友:

相关文章

vue 实现全选

vue 实现全选

Vue 实现全选功能 在 Vue 中实现全选功能通常需要结合复选框的状态管理,以下是几种常见的实现方式: 使用 v-model 绑定数组 通过 v-model 绑定一个数组来管理选中的项,全选时将…

vue实现安全免登录

vue实现安全免登录

Vue 实现安全免登录的方案 免登录功能通常通过持久化认证状态(如 Token)实现,但需兼顾安全性。以下是基于 Vue 的常见实现方案: 基于 Token 的免登录 登录成功后存储 Toke…

vue实现多用户登录

vue实现多用户登录

实现多用户登录的基本思路 在Vue中实现多用户登录通常需要结合后端API完成身份验证,并通过前端路由、状态管理(如Vuex或Pinia)和本地存储(如localStorage)来管理用户会话。以下是关…

实现vue组件

实现vue组件

Vue 组件的基本实现 Vue 组件是 Vue.js 的核心特性之一,允许将 UI 拆分为独立、可复用的模块。以下是实现 Vue 组件的几种方式: 单文件组件 (SFC) 使用 .vue 文件格式…

vue实现缩放

vue实现缩放

Vue 实现缩放的方法 在 Vue 中实现缩放功能可以通过多种方式完成,以下是一些常见的方法: 使用 CSS transform 属性 通过 CSS 的 transform: scale() 属性…

vue实现图库

vue实现图库

Vue 实现图库的基本方法 使用 Vue 实现图库功能可以通过多种方式完成,以下是一些常见的方法和实现步骤。 使用 Vue 和第三方库(如 Vue Gallery) 安装 vue-gallery 或…