当前位置:首页 > 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原型:

自己实现vue-router

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
}

实现动态路由

支持动态路径参数:

自己实现vue-router

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'
})

标签: vuerouter
分享给朋友:

相关文章

vue实现查询替换

vue实现查询替换

Vue 实现查询替换功能 在 Vue 中实现查询替换功能,可以通过数据绑定和字符串操作方法结合实现。以下是具体实现方式: 基础实现 <template> <div>…

vue前端实现打印功能

vue前端实现打印功能

使用Vue实现前端打印功能 在Vue项目中实现打印功能可以通过多种方式完成,以下是几种常见的方法: 使用window.print()方法 这是最简单的打印方式,直接调用浏览器的打印功能。 me…

vue实现签约合作弹窗

vue实现签约合作弹窗

实现签约合作弹窗的步骤 使用Vue实现签约合作弹窗可以通过组件化方式完成,结合模态框和表单交互逻辑。以下是具体实现方法: 1. 创建弹窗组件 新建一个Vue组件文件(如SignContractDia…

vue实现飘窗原理

vue实现飘窗原理

vue实现飘窗原理 飘窗效果通常指在页面上悬浮显示的弹窗或通知,跟随页面滚动或固定在某个位置。Vue实现这一效果主要依赖组件化开发、CSS定位和动态数据绑定。 组件结构设计 创建一个独立的Vue组件…

vue实现自定义登录

vue实现自定义登录

实现自定义登录的基本步骤 在Vue中实现自定义登录功能通常需要结合前端和后端技术。以下是一个基本的实现流程: 创建登录表单组件 使用Vue的单文件组件创建一个登录表单,包含用户名和密码输入框以及提交…

vue聊天实现

vue聊天实现

Vue 聊天应用实现步骤 创建 Vue 项目 使用 Vue CLI 或 Vite 初始化项目,安装必要依赖(如 Vue 3、Element UI 或 Vuetify 用于 UI 组件)。 npm c…