Vue数据响应式原理步骤解析

 更新时间:2025年06月10日 10:36:54   作者:teeeeeeemo  
Vue的数据响应式原理是其核心特性之一,它实现了数据变化自动驱动视图更新,下面给大家分别详解Vue 2.x和Vue 3.x的实现方式,感兴趣的朋友一起看看吧

Vue 的数据响应式原理是其核心特性之一,它实现了数据变化自动驱动视图更新。Vue 2.x 和 Vue 3.x 的实现方式不同,下面分别详解:

Vue 2.x 的响应式原理(基于 Object.defineProperty)

核心步骤:

数据劫持(Observer):
-遍历 data 中的每个属性,用 Object.defineProperty 重写其 getter/setter。
-每个属性关联一个 Dep 实例(依赖收集器)。依赖收集(Dependency Collection):
-当组件渲染时,会访问数据属性,触发 getter。
-此时 Dep 会记录当前 Watcher(每个组件对应一个渲染 Watcher)。派发更新(Dispatching Updates):
-当数据被修改时,触发 setter。
-Dep 通知所有关联的 Watcher 执行更新(如重新渲染组件)。数组的特殊处理:
-重写数组的 7 个方法(push/pop/shift/unshift/splice/sort/reverse),在调用这些方法时手动触发更新。
-通过 proto 继承改写后的数组方法(或直接覆盖原型)。

代码简化示例:

class Dep {
  constructor() {
    this.subs = new Set();
  }
  depend() {
    if (currentWatcher) this.subs.add(currentWatcher);
  }
  notify() {
    this.subs.forEach(watcher => watcher.update());
  }
}
function defineReactive(obj, key) {
  const dep = new Dep();
  let value = obj[key];
  Object.defineProperty(obj, key, {
    get() {
      dep.depend(); // 收集依赖
      return value;
    },
    set(newVal) {
      value = newVal;
      dep.notify(); // 触发更新
    }
  });
}

局限性:

  • 无法检测新增/删除属性 → 需用 Vue.set/Vue.delete。
  • 数组索引/长度修改无法监听 → 需用重写的方法或 Vue.set。
  • 递归遍历对象性能损耗。

Vue 3.x 的响应式原理(基于 Proxy)

Vue 3 使用 Proxy 替代 Object.defineProperty,彻底解决 Vue 2 的痛点。

核心步骤:

代理对象(Reactive):
-通过 Proxy 包裹目标对象,拦截 所有操作(增/删/改/查/遍历等)。
-每个对象关联一个 ReactiveEffect 集合。

依赖收集:
-当访问数据时,触发 get 拦截,收集当前活跃的 Effect(副作用函数)。

触发更新:
-当修改数据时,触发 set 或 deleteProperty 拦截,通知所有关联的 Effect 重新执行。

代码简化示例:

const targetMap = new WeakMap(); // 存储所有依赖
function track(target, key) {
  if (!activeEffect) return;
  let depsMap = targetMap.get(target);
  if (!depsMap) targetMap.set(target, (depsMap = new Map()));
  let dep = depsMap.get(key);
  if (!dep) depsMap.set(key, (dep = new Set()));
  dep.add(activeEffect); // 收集当前 Effect
}
function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  depsMap.get(key)?.forEach(effect => effect.run()); // 执行所有 Effect
}
const proxy = new Proxy(data, {
  get(target, key) {
    track(target, key); // 访问时收集依赖
    return Reflect.get(target, key);
  },
  set(target, key, value) {
    Reflect.set(target, key, value);
    trigger(target, key); // 修改时触发更新
    return true;
  }
});

优势:

  • 支持监听动态新增/删除属性
  • 支持监听数组索引和长度变化
  • 惰性收集:仅代理访问到的属性,减少初始化开销。
  • 统一处理对象/数组,无需特殊逻辑。

关键概念补充

副作用函数(Effect):
-Vue 3 使用 ReactiveEffect 封装更新逻辑(相当于 Vue 2 的 Watcher)。
-组件渲染、计算属性、侦听器都是副作用函数。

响应式 API:
-reactive():创建深层次响应式对象(基于 Proxy)。
-ref():将基本类型包装为 { value: … } 的响应式引用(通过 .value 访问)。
-computed/watch:基于 Effect 系统实现。

依赖清理:
-每次执行 Effect 前清理旧依赖,避免无效更新(如条件分支变化时)。

总结对比

特性Vue 2(Object.defineProperty)Vue 3(Proxy)
对象监听递归遍历属性直接代理整个对象
新增/删除属性不支持(需 Vue.set)支持
数组监听需重写方法直接支持索引修改
性能初始化递归消耗大按需代理,内存更优
兼容性支持 IE9+不支持 IE(需 Polyfill)

Vue 3 的响应式系统独立为库 @vue/reactivity,可脱离框架使用。

到此这篇关于Vue数据响应式原理解析的文章就介绍到这了,更多相关Vue数据响应式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题

    解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题

    这篇文章主要介绍了解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • Vue页面骨架屏的实现方法

    Vue页面骨架屏的实现方法

    在开发webapp的时候总是会受到首屏加载时间过长的影响,越来越多的APP采用了“骨架屏”的方式去提升用户体验。这篇文章主要介绍了Vue页面骨架屏的实现方法,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • vue微信分享出来的链接点开是首页问题的解决方法

    vue微信分享出来的链接点开是首页问题的解决方法

    这篇文章主要为大家详细介绍了vue微信分享出来的链接点开是首页问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • Vue2使用vue-video-player实现断点续传功能

    Vue2使用vue-video-player实现断点续传功能

    断点续传是指在文件传输过程中,如果传输被中断或者发生错误,可以从上一次中断的地方继续传输,而不是从头开始,这对于大文件的传输尤为重要,本文给大家介绍了Vue2使用vue-video-player实现断点续传功能,需要的朋友可以参考下
    2025-07-07
  • vue created钩子函数与mounted钩子函数的用法区别

    vue created钩子函数与mounted钩子函数的用法区别

    这篇文章主要介绍了vue created钩子函数与mounted钩子函数的用法区别,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • VUE mixin 使用示例详解

    VUE mixin 使用示例详解

    混入mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能,一个混入对象可以包含任意组件选项,接下来通过本文给大家介绍VUE mixin 使用,需要的朋友可以参考下
    2022-08-08
  • vue+elementUI(el-upload)图片压缩,默认同比例压缩操作

    vue+elementUI(el-upload)图片压缩,默认同比例压缩操作

    这篇文章主要介绍了vue+elementUI(el-upload)图片压缩,默认同比例压缩操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Vue表单提交点击事件只允许点击一次的实例

    Vue表单提交点击事件只允许点击一次的实例

    这篇文章主要介绍了Vue表单提交点击事件只允许点击一次的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Vue.js原理分析之observer模块详解

    Vue.js原理分析之observer模块详解

    这篇文章主要介绍了Vue.js中observer模块的相关资料,文中通过原理分析介绍还是相对的详细,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-02-02
  • vue封装自定义分页器组件与使用方法分享

    vue封装自定义分页器组件与使用方法分享

    这篇文章主要给大家介绍了关于vue封装自定义分页器组件与使用方法的相关资料,非常的好用,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-01-01

最新评论