vue2与vue3的区别

87 阅读1分钟

vue2

通俗原理: 通过Object.defineProperty() 进行数据劫持的同时, 收集关联影响。比如发现响应式数据时,收集相关geter setter 的影响,(通过订阅发布模式触发render 渲染)如果有影响,对比更新虚拟dom Tree 重新渲染)

1.Object.defineProperty()定义对象属性特征

// Object.defineProperty(对象,属性名, 属性描述)
const obj = {}
// 通过此方式进行数据劫持
Object.defineProperty(obj, 'name', {
  value: '属性值',
  writable: true, // 是否可写
  enumerable: true, // 是否可枚举
})
console.log(obj.name) // 属性值
2. Object.defineProperty() 的get()和set()
const obj = {
}
const obj2 = Object.create(obj) // 继承 obj 对象
// 通过此方式进行数据劫持
Object.defineProperty(obj,'age', {
  // value: '属性值', 不能与get set 同时出现
  // writable: true, // 是否可写 不能与get set 同时出现
  // enumerable: true, // 是否可枚举  
  get() {
    console.log('get')
    return value
  },
  set(nVal) {
    console.log('set');
    value = nVal
  }
})
obj.age = 88
console.log(obj.age) // 属性值

vue3 中的proxy基本用法

通俗原理: (同v2相似)通过Proxy(好处:支持 Map Set) 进行数据劫持的同时, 收集副作用。比如发现响应式数据时,收集相关geter setter 的影响,(通过订阅发布模式触发render 渲染)如果有影响,对比更新虚拟dom Tree 重新渲染)

const obj = {}
const proxyObj = new Proxy(obj, {
  get(target, key, receiver) {
    console.log('get 收集effect');
    if (key in target) {
      return target[key] || Reflect.get(target, key)
    } else {
      throw new ReferenceError(`${key}不存在,抓不到它`)
    }
  },
  set(target, key, value, receiver) { // 4个参数 target, key, value, receiver
    console.log('set触发 收集effect')
    console.log(receiver === obj) // false
    console.log(receiver === proxyObj) // true
    // target[key] = value
    return Reflect.set(target, key, value) // 源码通过 Reflect进行操作后返回一个布尔值
  }
})
proxyObj.name = 'lllll'
console.log(proxyObj.name)