当前位置:首页 > VUE

vue 响应式实现

2026-01-15 06:03:26VUE

Vue 响应式实现原理

Vue 的响应式系统通过数据劫持结合发布-订阅模式实现,核心是 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)。

数据劫持(Vue 2.x)

Vue 2.x 使用 Object.defineProperty 递归遍历对象的属性,将其转换为 getter/setter:

vue 响应式实现

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取 ${key}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`设置 ${key}: ${newVal}`);
        val = newVal;
        // 触发更新
      }
    }
  });
}

依赖收集与派发更新

每个响应式属性关联一个 Dep(依赖管理器),在 getter 中收集依赖(Watcher),在 setter 中通知更新:

vue 响应式实现

class Dep {
  constructor() {
    this.subs = new Set();
  }
  addSub(watcher) {
    this.subs.add(watcher);
  }
  notify() {
    this.subs.forEach(watcher => watcher.update());
  }
}

// Watcher 示例
class Watcher {
  update() {
    console.log('视图更新');
  }
}

Vue 3.x 的 Proxy 实现

Vue 3.x 改用 Proxy 实现更高效的响应式:

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key); // 依赖收集
      return Reflect.get(target, key);
    },
    set(target, key, value) {
      Reflect.set(target, key, value);
      trigger(target, key); // 触发更新
    }
  });
}

数组响应式处理

Vue 2.x 通过重写数组的变异方法(如 pushpop)实现响应式:

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop'].forEach(method => {
  const original = arrayProto[method];
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args);
    // 触发更新逻辑
    return result;
  };
});

响应式系统的局限性

  • 对象属性添加/删除:Vue 2.x 需通过 Vue.set/Vue.delete 触发响应。
  • 数组索引修改:直接通过索引修改元素(如 arr[0] = newVal)不会触发更新。
  • Proxy 兼容性:Vue 3.x 的 Proxy 不支持 IE11 及以下浏览器。

性能优化建议

  • 避免频繁操作大型响应式对象。
  • 使用 Object.freeze() 冻结不需要响应式的数据。
  • 在 Vue 3.x 中,通过 shallowRefshallowReactive 减少深层响应式开销。

以上实现展示了 Vue 响应式系统的核心逻辑,实际源码中还包含虚拟 DOM 比对、批量异步更新等优化策略。

标签: vue
分享给朋友:

相关文章

vue实现单点

vue实现单点

Vue 实现单点登录(SSO)方案 单点登录(SSO)允许用户在多个相关但独立的系统中使用同一组凭证登录。以下是基于 Vue 的实现方案: 基于 OAuth2/OpenID Connect 的实现…

vue实现公告

vue实现公告

Vue 实现公告功能的方法 公告功能通常需要实现滚动展示、自动切换或固定显示的效果。以下是几种常见的实现方式: 使用 marquee 标签实现滚动公告 <template> &l…

vue轮询实现

vue轮询实现

Vue 轮询实现方法 在 Vue 中实现轮询可以通过以下几种方式: 使用 setInterval data() { return { pollInterval: null }…

vue实现看板

vue实现看板

Vue 实现看板功能 使用 Vue 实现看板功能可以通过组件化开发、状态管理和拖拽库结合完成。以下是一个完整的实现方案: 基础项目结构 src/ ├── components/ │ ├── Ka…

vue实现长按

vue实现长按

Vue 实现长按功能的方法 在 Vue 中实现长按功能可以通过原生事件监听或自定义指令完成。以下是几种常见实现方式: 使用原生事件监听 通过 @mousedown 和 @mouseup 或 @tou…

vue实现list

vue实现list

Vue 实现列表渲染 在 Vue 中,可以使用 v-for 指令来渲染列表。v-for 指令基于一个数组或对象来渲染一个列表,可以遍历数组或对象的属性。 基本列表渲染 <template>…