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 是响应式的)
  • 组件生命周期管理
  • 滚动行为控制
  • 路由元信息等
相关推荐
志尊宝1 小时前
Vue3 零基础每日笔记(032):Suspense 与异步组件——懒加载与顶层 await 终极方案
前端·javascript·vue.js·笔记·html5
Alice-YUE1 小时前
前端速通 Agent:5 个项目,一条学习路径
前端·大模型·ai agent·学习路径·deerflow
是立不是利1 小时前
前端分页逻辑与边界场景实战解析
前端·javascript
小聪7081 小时前
elpis-core 动态组件扩展设计
前端
Amos_Web2 小时前
Rspack 源码解析(七):Module、Chunk 与加载树优化
前端·rust·源码阅读
OpenTiny社区2 小时前
从开发到运行:OpenTiny NEXT 如何构建 Agent 时代的 Web 应用?
前端·github·ai编程
愿得一猪蹄2 小时前
前端性能优化,Core Web Vitals 三个指标到底怎么改
前端
xy34532 小时前
Axure 9.0 中继器创建与设置步骤
前端·ui·html·axure·原型·产品设计
FEF前端团队2 小时前
01# Vibe Coding工作流设计思维:前端开发者的协作框架
前端·cursor·vibecoding
计算机魔术师2 小时前
OpenAI 发布模型错位报告框架,披露未发布模型自行修改自身指令案例
前端