vue的响应式原理

vue2的响应式原理

  1. 属性描述符,也就是对对象的属性进行劫持
  • 通过 get收集依赖(收集使用该数据的组件),set 派发更新(通知依赖的组件重新渲染)

    • 依赖收集:每个组件实例对应一个 watcher对象,当组件渲染访问数据时,会触发属性的getter,将当前的watcher添加到依赖列表中(dep)
    • 派发更新: 当数据变化时触发setter,Dep会通知所关联的watcher重新计算从而触发组件重新渲染
  • 注意 :数组的响应式 是通过重写数组的方法(push、pop、splice)来实现对数组变化的监听,因为这些方法无法通过 object.defineProperty直接监听的

js 复制代码
Object.defineProperty(obj,'a',{
	value:10,
	writable:false,// 不可重写
	enumerable:false,// 不可遍历
	configurable:false,// 不可修改值本身
})

// vue 响应式简化版实现
function defineReactive(obj, key, val) {
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    get() {
      if (Dep.target) { // Dep.target 是当前 Watcher
        dep.addSub(Dep.target); // 收集依赖
      }
      return val;
    },
    set(newVal) {
      val = newVal;
      dep.notify(); // 通知所有 Watcher 更新
    },
  });
}

vue3的响应式原理

  • vue 3 使用Proxy代替 Object.defineProperty, 解决了vue2的局限性,(如无法检查对象属性的新增和删除,数组索引的直接赋值等)提高了性能
    • Proxy he reflect 的区别

      • Proxy:可以拦截对象的整个操作(读写,增删)
      • reflect 只能操作对象
    • 响应式API : reactive 和 ref

      • reactive(obj):将普通对象转换为响应式对象(通过 Proxy 代理)
      • ref(value):将基本类型值包装为响应式对象(通过 .value 访问)
    • 依赖和收集

      • track: 再getter中追踪依赖(类似vue2的dep)
      • trigger: 在setter 中触发依赖
js 复制代码
// 简化版实现
function reactive(obj) {
  return new Proxy(obj, {
    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;
    },
  });
}

‌Vue 2 vs. Vue 3 响应式对比

‌特性 Vue 2 (Object.defineProperty)‌ Vue 3 (Proxy)
对象属性监听 需要遍历属性递归劫持 直接代理整个对象
数组监听 重写数组方法 直接监听索引变化
新增/删除属性 需手动调用 Vue.set/Vue.delete 自动支持
性能 递归劫持有性能损耗 惰性劫持,按需触发
相关推荐
musk12122 分钟前
electron 打包太大 试试 tauri , tauri 安装打包demo
前端·electron·tauri
翻滚吧键盘31 分钟前
js代码09
开发语言·javascript·ecmascript
万少1 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL1 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
rzl021 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang1 小时前
前端如何实现电子签名
前端·javascript·html5
海天胜景1 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼1 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
蓝婷儿1 小时前
每天一个前端小知识 Day 21 - 浏览器兼容性与 Polyfill 策略
前端
百锦再2 小时前
Vue中对象赋值问题:对象引用被保留,仅部分属性被覆盖
前端·javascript·vue.js·vue·web·reactive·ref