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 是响应式的)
  • 组件生命周期管理
  • 滚动行为控制
  • 路由元信息等
相关推荐
星空椰5 分钟前
JavaScript 基础入门:从零开始掌握变量与数据类型
开发语言·前端·javascript·ecmascript
千寻简10 分钟前
一个让 Claude Code 顺手很多的状态栏插件:claude-hud
前端·后端
Ruihong19 分钟前
你的 Vue 3 生命周期,VuReact 会编译成什么样的 React?
vue.js·react.js·面试
HelloReader19 分钟前
Qt Quick Controls 全览控件、弹窗、导航与样式定制(十一)
前端
意法半导体STM3223 分钟前
【官方原创】STM32 USBx Host HID standardalone移植示例 LAT1449
开发语言·前端·stm32·单片机·嵌入式硬件
竹林81824 分钟前
用wagmi v2构建DeFi前端:从连接钱包到读取合约数据的完整实战与避坑指南
前端·javascript
over69724 分钟前
面试官视角:TypeScript Pick 工具类型深度解析与手写实现
前端·面试
木斯佳26 分钟前
前端八股文面经大全:字节AIDP前端一面(2026-04-13)·面经深度解析
前端·音视频·webrtc·断点续传
Kinghiee29 分钟前
从零打造生产级前端错误监控 SDK:架构设计与 Vue3 实践
前端·javascript·vue.js·去重·错误捕获·上报·离线持久化
小凡同志33 分钟前
OpenSpec 手把手实战:从零跑通一个完整功能
前端·ai编程·claude