当前位置:首页 > VUE

vue底层实现远离

2026-02-11 06:21:15VUE

Vue 的响应式原理

Vue 的响应式系统基于 ES5 的 Object.defineProperty(Vue 2)或 ES6 的 Proxy(Vue 3)实现。核心是通过数据劫持结合发布-订阅模式,自动追踪依赖并在数据变化时触发更新。

Vue 2 实现方式:

  • 通过 Object.defineProperty 递归遍历数据对象,将属性转换为 getter/setter。
  • 每个组件实例对应一个 Watcher 实例,在 getter 中收集依赖(Watcher),在 setter 中通知依赖更新。
  • 数组方法(如 pushpop)通过重写原生方法实现响应式。
// 简化版数据劫持示例
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log('收集依赖');
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log('触发更新');
      val = newVal;
    }
  });
}

Vue 3 实现方式:

vue底层实现远离

  • 改用 Proxy 代理整个对象,无需递归初始化属性,性能更好。
  • Reflect 配合 Proxy 实现更规范的元编程操作。
  • 新增 effect 函数替代 Watcher,依赖收集更精确。
// 简化版 Proxy 实现
const reactive = (target) => {
  return new Proxy(target, {
    get(target, key, receiver) {
      track(target, key); // 依赖收集
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      Reflect.set(target, key, value, receiver);
      trigger(target, key); // 触发更新
      return true;
    }
  });
};

虚拟 DOM 与 Diff 算法

Vue 使用虚拟 DOM 减少直接操作真实 DOM 的开销。当数据变化时,生成新的虚拟 DOM 树,通过 Diff 算法比较新旧树的差异,最小化 DOM 操作。

关键优化:

vue底层实现远离

  • 同级比较(同层比对),时间复杂度 O(n)。
  • 通过 key 属性复用相同节点。
  • 双端比较算法(Vue 3 优化为更高效的算法)。

模板编译流程

Vue 模板通过以下步骤转换为渲染函数:

  1. 解析:将模板字符串转换为 AST(抽象语法树)。
  2. 优化:标记静态节点,避免重复渲染。
  3. 生成:将 AST 转换为可执行的渲染函数代码。
// 示例模板
<template>
  <div>{{ message }}</div>
</template>

// 编译后渲染函数
function render() {
  return _c('div', [_v(_s(message))]);
}

组件化实现

Vue 组件本质是可复用的 Vue 实例,通过 Vue.extend()defineComponent 创建。核心机制包括:

  • 组件注册:全局或局部注册组件选项。
  • 生命周期管理:从 beforeCreatedestroyed 的钩子调用。
  • 插槽机制:通过 $slots$scopedSlots 实现内容分发。

异步更新队列

Vue 通过异步队列(nextTick)批量处理数据变更后的 DOM 更新:

  • 使用 Promise > MutationObserver > setTimeout 的降级策略实现微任务/宏任务调度。
  • 确保多次数据变更只触发一次渲染,避免不必要的计算。
// nextTick 实现原理
let callbacks = [];
function nextTick(cb) {
  callbacks.push(cb);
  if (!pending) {
    pending = true;
    Promise.resolve().then(flushCallbacks);
  }
}
function flushCallbacks() {
  pending = false;
  callbacks.forEach(cb => cb());
}

标签: 底层vue
分享给朋友:

相关文章

vue中如何实现循环

vue中如何实现循环

在 Vue 中实现循环 Vue 提供了 v-for 指令用于实现循环渲染列表数据。v-for 可以遍历数组、对象或数字范围,生成动态的 DOM 元素。 遍历数组 使用 v-for 遍历数组时,语法…

vue 实现tabs

vue 实现tabs

Vue 实现 Tabs 组件的方法 使用动态组件和 v-for 在 Vue 中实现 Tabs 可以通过动态组件和 v-for 指令结合完成。定义一个 tabs 数组,包含每个标签的标题和对应的组件。…

vue实现流程

vue实现流程

Vue 实现流程的基本步骤 安装 Vue.js 可以通过 CDN 引入或使用 npm/yarn 安装。 CDN 方式: <script src="https://cdn.jsdelivr.…

vue 动画 实现

vue 动画 实现

vue 动画实现方法 Vue 提供了多种方式实现动画效果,主要包括过渡动画和动态动画两类。 使用 <transition> 组件实现基础过渡 通过 Vue 内置的 <transit…

vue实现suspense

vue实现suspense

Vue 3 中实现 Suspense Suspense 是 Vue 3 引入的一个内置组件,用于处理异步依赖的加载状态。它允许在等待异步组件或异步数据加载时显示一个后备内容(fallback),直到异…

vue alert实现

vue alert实现

使用 Vue 实现 Alert 组件 在 Vue 中实现 Alert 组件可以通过自定义组件或结合第三方库完成。以下是几种常见方法: 自定义 Alert 组件 创建一个可复用的 Alert 组件,…