当前位置:首页 > VUE

实现简易vue响应式

2026-01-21 15:10:14VUE

实现简易 Vue 响应式系统

Vue 的响应式系统核心是通过 Object.definePropertyProxy 拦截数据变化,并结合依赖收集与派发更新机制实现。以下是一个基于 Object.defineProperty 的简化实现:

实现简易vue响应式

数据劫持(Observer)

通过递归遍历对象属性,将其转换为响应式:

实现简易vue响应式

function observe(data) {
  if (typeof data !== 'object' || data === null) return;
  new Observer(data);
}

class Observer {
  constructor(data) {
    this.walk(data);
  }

  walk(data) {
    Object.keys(data).forEach(key => {
      defineReactive(data, key, data[key]);
    });
  }
}

function defineReactive(obj, key, val) {
  observe(val); // 递归处理嵌套对象
  const dep = new Dep(); // 每个属性对应一个依赖管理器

  Object.defineProperty(obj, key, {
    get() {
      Dep.target && dep.addSub(Dep.target); // 收集依赖
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      observe(newVal); // 新值是对象时继续劫持
      dep.notify(); // 触发更新
    }
  });
}

依赖管理(Dep)

管理所有依赖(Watcher)并在数据变化时通知:

class Dep {
  constructor() {
    this.subs = [];
  }

  addSub(sub) {
    this.subs.push(sub);
  }

  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

Dep.target = null; // 全局标记当前正在计算的Watcher

观察者(Watcher)

封装依赖更新逻辑:

class Watcher {
  constructor(vm, key, cb) {
    this.vm = vm;
    this.key = key;
    this.cb = cb;
    Dep.target = this;
    this.oldValue = vm[key]; // 触发getter收集依赖
    Dep.target = null;
  }

  update() {
    const newValue = this.vm[this.key];
    if (newValue !== this.oldValue) {
      this.cb(newValue);
      this.oldValue = newValue;
    }
  }
}

使用示例

const data = { count: 1 };
observe(data);

new Watcher(data, 'count', (val) => {
  console.log(`count更新为: ${val}`);
});

data.count = 2; // 输出: "count更新为: 2"

注意事项

  1. 数组变异方法需要特殊处理(如 push/pop 等)
  2. 现代 Vue 版本已改用 Proxy 实现,可避免 Object.defineProperty 的局限性(如新增属性检测)
  3. 实际实现还需处理虚拟DOM、批量更新等复杂逻辑

标签: 简易vue
分享给朋友:

相关文章

vue实现皮肤切换

vue实现皮肤切换

实现皮肤切换的基本思路 在Vue中实现皮肤切换功能,通常涉及动态修改CSS变量或类名。核心是通过状态管理当前主题,并在组件中应用对应的样式。 使用CSS变量实现主题切换 CSS变量(自定义属性)是实…

vue前端实现注册

vue前端实现注册

使用 Vue 实现用户注册功能 环境准备 确保已安装 Vue CLI 或通过 CDN 引入 Vue。若使用 Vue CLI,需安装 axios 或其他 HTTP 库用于后端通信。 注册表单组件 创…

vue实现购物按钮

vue实现购物按钮

Vue 购物按钮实现方法 基础按钮实现 使用 Vue 的模板语法创建基础按钮组件,绑定点击事件处理购物逻辑: <template> <button @click="addTo…

用vue实现搜索查询

用vue实现搜索查询

实现搜索查询的基本思路 在Vue中实现搜索查询功能通常涉及以下几个核心部分:数据绑定、事件监听、过滤逻辑和UI反馈。以下是一个完整的实现方案。 数据绑定与输入框 创建一个Vue组件,包含一个输入框用…

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { lette…

vue实现发送值接受值

vue实现发送值接受值

Vue 实现父子组件传值 父组件向子组件传值(props) 父组件通过 v-bind 或简写 : 向子组件传递数据。子组件通过 props 接收数据。 父组件代码: <template&g…