面试:vue2和vue3的双向绑定原理有什么不同

1、不同

1.1 响应式实现原理

Vue2 - Object.defineProperty

// Vue2 的响应式原理简化实现
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;
        // 触发更新
        updateView();
      }
    }
  });
}

const data = { name: 'Vue2' };
defineReactive(data, 'name', data.name);
data.name = 'New Value'; // 触发 setter

局限性:

  • 无法检测对象属性的添加/删除
  • 无法检测数组索引和长度的变化
  • 需要额外的 API(Vue.set, Vue.delete)
// Vue2 的问题示例
const vm = new Vue({
  data: {
    user: { name: 'John' },
    list: [1, 2, 3]
  }
});

// ❌ 无法响应式
vm.user.age = 25;           // 新增属性
delete vm.user.name;        // 删除属性
vm.list[0] = 999;          // 数组索引设置
vm.list.length = 0;        // 数组长度修改

// ✅ 必须使用特殊 API
Vue.set(vm.user, 'age', 25);
Vue.set(vm.list, 0, 999);

Vue3 - Proxy:

// Vue3 的响应式原理简化实现
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      console.log(`读取 ${String(key)}`);
      const result = Reflect.get(target, key, receiver);
      return typeof result === 'object' ? reactive(result) : result;
    },
    set(target, key, value, receiver) {
      console.log(`设置 ${String(key)}: ${value}`);
      const result = Reflect.set(target, key, value, receiver);
      // 触发更新
      updateView();
      return result;
    },
    deleteProperty(target, key) {
      console.log(`删除 ${String(key)}`);
      const result = Reflect.deleteProperty(target, key);
      updateView();
      return result;
    }
  });
}

const data = reactive({ name: 'Vue3', list: [1, 2, 3] });
data.name = 'New Value';        // 触发 set
data.age = 25;                  // 触发 set - 新增属性
delete data.name;               // 触发 deleteProperty
data.list[0] = 999;            // 触发 set - 数组索引
data.list.push(4);             // 触发 set - 数组方法

优势:

  • ✅ 支持对象属性的添加/删除
  • ✅ 支持数组索引和长度的变化
  • ✅ 深度监听,性能更好
  • ✅ 不需要特殊 API

1.2 性能对比

在这里插入图片描述

1.3 源码结构差异

Vue2 响应式结构

// Vue2 源码简化
class Observer {
  constructor(value) {
    this.value = value;
    this.walk(value);
  }
  
  walk(obj) {
    Object.keys(obj).forEach(key => {
      defineReactive(obj, key, obj[key]);
    });
  }
}

function defineReactive(obj, key, val) {
  const dep = new Dep(); // 每个属性一个依赖收集器
  
  // 递归处理嵌套对象
  if (typeof val === 'object') {
    new Observer(val);
  }
  
  Object.defineProperty(obj, key, {
    get() {
      if (Dep.target) {
        dep.depend(); // 收集依赖
      }
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        val = newVal;
        // 新值是对象也要响应式
        if (typeof newVal === 'object') {
          new Observer(newVal);
        }
        dep.notify(); // 通知更新
      }
    }
  });
}

Vue3 响应式结构

// Vue3 源码简化
const reactiveMap = new WeakMap();

function reactive(target) {
  return createReactiveObject(target, reactiveMap);
}

function createReactiveObject(target, proxyMap) {
  // 缓存检查
  const existingProxy = proxyMap.get(target);
  if (existingProxy) return existingProxy;
  
  const proxy = new Proxy(target, {
    get(target, key, receiver) {
      const res = Reflect.get(target, key, receiver);
      // 依赖收集
      track(target, key);
      // 惰性递归代理
      if (typeof res === 'object' && res !== null) {
        return reactive(res);
      }
      return res;
    },
    set(target, key, value, receiver) {
      const oldValue = target[key];
      const result = Reflect.set(target, key, value, receiver);
      if (result && oldValue !== value) {
        // 触发更新
        trigger(target, key);
      }
      return result;
    }
  });
  
  proxyMap.set(target, proxy);
  return proxy;
}

2、面试回答技巧

可以这样组织回答:“Vue2 和 Vue3 在双向绑定原理上的主要区别在于响应式系统的实现”

  • 核心技术不同:
    • Vue2 使用 Object.defineProperty 实现数据劫持
    • Vue3 使用 Proxy 实现代理拦截
  • 能力差异:
    • Vue2 无法检测对象属性的添加/删除和数组索引变化,需要 Vue.set/Vue.delete
    • Vue3 可以全面检测各种数据变化,包括新增属性、数组操作等
  • 性能优化:
    • Vue2 初始化时递归遍历所有属性,性能开销较大
    • Vue3 使用惰性代理,按需响应,内存占用更优
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳与星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值