Vue Router 监听地址变化的核心逻辑示意

Vue Router 监听地址变化的核心逻辑示意

搞个简化版本主要展示下 Vue Router最核心的监听和更新机制。

核心实现原理代码

javascript 复制代码
// 简化版 Vue Router 核心逻辑示例
class VueRouter {
  constructor(options) {
    this.routes = options.routes;
    this.current = window.location.hash.slice(1) || '/';
    
    // 监听 hashchange 事件(哈希模式)
    window.addEventListener('hashchange', () => {
      this.current = window.location.hash.slice(1);
      this.updateView();
    });
    
    // 或者监听 popstate 事件(历史模式)
    window.addEventListener('popstate', (event) => {
      if (event.state && event.state.route) {
        this.current = event.state.route;
        this.updateView();
      }
    });
    
    // 初始渲染
    this.updateView();
  }
  
  // 更新视图的核心方法
  updateView() {
    // 1. 根据当前路径匹配路由
    const matchedRoute = this.matchRoute(this.current);
    
    // 2. 获取对应的组件
    const component = matchedRoute.component;
    
    // 3. 渲染组件到 router-view
    const routerView = document.querySelector('router-view');
    if (routerView && component) {
      // 清除旧内容
      routerView.innerHTML = '';
      
      // 创建新组件实例并挂载
      const componentInstance = new component();
      routerView.appendChild(componentInstance.$el || componentInstance);
    }
  }
  
  // 路由匹配算法
  matchRoute(path) {
    return this.routes.find(route => route.path === path) || 
           this.routes.find(route => route.path === '*'); // 通配符
  }
  
  // 编程式导航
  push(path) {
    // 哈希模式
    window.location.hash = '#' + path;
    
    // 或历史模式
    // window.history.pushState({ route: path }, '', path);
    
    this.current = path;
    this.updateView();
  }
  
  // 替换当前路由
  replace(path) {
    // 哈希模式
    window.location.replace('#' + path);
    
    // 或历史模式
    // window.history.replaceState({ route: path }, '', path);
    
    this.current = path;
    this.updateView();
  }
}

// 使用示例
const router = new VueRouter({
  routes: [
    { path: '/', component: HomeComponent },
    { path: '/about', component: AboutComponent },
    { path: '/user/:id', component: UserComponent },
    { path: '*', component: NotFoundComponent }
  ]
});

监听机制流程图

用户 浏览器 Vue Router RouterView 组件 1. 初始加载 触发 hashchange/popstate 解析当前路径 /about 匹配路由配置 获取 AboutComponent 指令渲染 AboutComponent 挂载组件实例 2. 用户点击链接 点击 /user/123 URL 变化,触发 hashchange 执行路由守卫 beforeEach 解析新路径 /user/123 提取参数 {id: 123} 获取 UserComponent 销毁旧组件,渲染新组件 挂载 UserComponent(123) 执行 afterEach 钩子 用户 浏览器 Vue Router RouterView 组件

关键点

  1. 两种监听模式

    • 哈希模式 :监听 hashchange 事件
    • 历史模式 :监听 popstate 事件
  2. 核心流程

    • 地址变化 → 事件触发 → 解析路径 → 匹配路由 → 获取组件 → 更新视图
  3. 视图更新

    • 找到 <router-view> 容器
    • 销毁旧组件(清理资源)
    • 创建并挂载新组件
  4. 扩展功能

    • 路由守卫(beforeEach、afterEach)
    • 动态路由参数(/user/:id
    • 嵌套路由(多级 <router-view>
    • 懒加载(异步组件)

实际 Vue Router 的实现会更复杂,包括:

  • 响应式系统(currentRoute 是响应式的)
  • 组件生命周期管理
  • 滚动行为控制
  • 路由元信息等
相关推荐
Hilaku14 小时前
当 AI 一天写完一周的代码,我们还剩什么优势?
前端·javascript·程序员
无责任此方_修行中14 小时前
换个版本号就能升级?可没那简单:pnpm 11 升级踩坑记
javascript·后端·npm
尘世中一位迷途小书童14 小时前
无人机航线里的云台角度怎么调?Cesium 做了个视锥 + 鹰眼联动
前端·javascript·数据可视化
张元清14 小时前
React useMeasure Hook:用 ResizeObserver 测量 DOM 元素 (2026)
javascript·react.js
思码梁田14 小时前
CSS display 属性:从元素类型转换到隐藏元素的实用指南
前端·css·display·inline·block·none·inline-block
Csvn14 小时前
⚡ Vite 依赖预构建(optimizeDeps)的 3 个经典坑:改了源码不生效、新增依赖 404、缓存怎么清都不行
前端
A242073493014 小时前
Vue3 + TypeScript:后端数据在表格内渲染后进行增删改的完整实现步骤
前端·javascript·typescript
他们叫我 悦儿遥遥雨14 小时前
.NET 8 Web开发入门(六):Blazor 全栈开发——告别 JavaScript 焦虑
前端·javascript·.net
用户21816970493014 小时前
Flutter(九)StatelessWidget StatefullWidget
前端
paopaokaka_luck14 小时前
基于springboot3+vue3的乡村医生诊疗管理系统(AI助手、协同过滤算法、webSocket实时聊天、Echarts图形化分析)
前端·网络·人工智能·spring boot·websocket·网络协议·echarts