vue 3.0 响应式数据原理

vue3.0 数据响应式原理的实现: 
  1: 实现原理:
    通过(Proxy)代理实现: 拦截对象中任意属性的变化, 包括属性值的读写, 属性的添加, 属性的删除等操作。

  2: 通过(Reflect)(反射);  被代理的对象, 属性进行操作。

MDN 文档中描述的Proxy 与Reflect:
 new Proxy(data, {
   // 拦截读取属性值
   get (target, prop) {
     return Reflect.get(target, prop);
   },
   // 拦截设置属性值或者添加属性值
   set(target, prop, value) {
     return Reflect.set(target, prop, value)
   },
   // 拦截删除删除属性
   deleteProperty(target, prop) {
      return reflect.deleteProperty(target, value);
   }
 })

 vue3.0 中不存在vue2.0 中说的这些问题
   在一个对象中新增, 删除, 修改属性,  界面不会自动更新。
   直接通过下标修改数组, 界面不会自动更新。

  vue2.0 中实现数据响应式原理: 
  let person {
     name: "李明", 
     age: 18
  }

  // 模拟vue2.0 中实现响应式
  let p = {};
  Object.defineProperty(p, 'name', {
    get() {  // 有人读取name 属性调用
       return person.name
    },
    set(value) {  // 有人修改name 属性是调用
       person.name = value
    }
  })
  Object.defineProperty(p, 'age', {
    get() {  // 有人读取name 属性调用
       return person.age
    },
    set(value) {  // 有人修改name 属性是调用
       person.age= value
    }
  })
 Object.defindProperty(person, 'sex', {
   value:"男",  // 设置值
   emnumable: true,  // 可枚举的,  默认值为false
   writeable: true,  // 可以被修改的, 默认值为false
   
 })

 vue3.0 中proxy 就是代理的含义: 
 window 全局身上有一个proxy 代理对象:
 const p = new proxy(person, {}),  // 配置对象
 对属性进行增删改查的操作proxy 都可以捕获到。
 
 vue3.0 实现响应式的模拟:
  const p = new proxy(person, {
    // 有人读取p 身上的某个属性
    get(target, propName) {
      console.log(`有人读取了p身上的${propName}属性`, 更新界面);
      return target[propName];  return 出去一个返回值
    }, 
    // 给p对象身上增加/ 修改某个属性时调用
    set(target, propName, value) {
      console.log(`有人修改/增加了p身上的${propName}属性`, 更新界面);
      target[propName] = value;
    },


    deleteproperty(target, propName) {
      console.log(`有人删除了p身上的${propName}属性`, 更新界面);
      return delete target[propName];   // 删除一个属性
    }
  })
  proxy 可以实现数据的增删改查

 从对象中读取一个属性:  使用window 全局身上有一个Reflect(反射)
 let object = {
   a: 1,
   b: 2
 }

 第一种: object.a = 1; 
 第二种: 使用window 全局身上有一个Reflect(反射)  Reflect.get(object, a);
  第一个参数要读取的对象, 第二个参数要读取对象的属性值

 修改对象身上的某一个属性:
 可以使用: object.a = 666;  直接拿到属性值进行修改。
 第二种方法: object.set(obj, 'a', 666);   // 第一个要修改的对象, 第二个参数要修改的属性名, 第 
 三个参数就是要修改的值。
 
 删除对象中某个属性: 
 let object = {
   name: "李明",
   age: 18   // 年龄
 }
 删除对象某个属性, 使用delete 方法:  delete.object.name  删除object 对象中name 属性。

 Reflect.deleteProperty(object, a)   使用Reflect(反射)  deleteProperty  删除对象身上属性。
 对一个属性的基本操作, 体现不出来Reflect 的威力: 
 Reflect 身上也有definedProperty() 属性:
 
 Reflect.defineProperty()  身上是有返回值的。 返回值是布尔值
 Reflect 的使用在框架封装使用上好处: 
 Reflect 是一个内置对象, 它提供了可以拦截javaScript 操作方法。 方法与代理处理程序相同。 Reflect 不是一个对象, 因此它是不可以new 的, 不可以当做构造函数使用。
 new Reflect() //错误的写法

 Reflect提供了一些静态方法, 静态方法是指只能通过对象自身访问的的方法。
 1、Reflect.apply()
2、Reflect.construct()
3、Reflect.defineProperty()
4、Reflect.deleteProperty()
5、Reflect.enumerate()
6、Reflect.get()
7、Reflect.getOwnPropertyDescriptor()
8、Reflect.getPrototypeOf()
9、Reflect.has()
10、Reflect.isExtensible()
11、Reflect.ownKeys()
12、Reflect.preventExtensions()
13、Reflect.set()
14、Reflect.setPrototypeOf()

静态方法的使用:
 Reflect.get() 方法:
 Rlflect.get() 获取目标对象指定的key的value.

 let object = {
   a:1,
 }
 let s1 = Reflect.get(obj, "a");
 console.log(s1)   ===>获取指定对象的属性名

  vue3.0 实现响应式的实现:
  const p = new proxy(person, {
    // 有人读取p 身上的某个属性
    get(target, propName) {
      console.log(`有人读取了p身上的${propName}属性`, 更新界面);
      return Reflect.get(target, propName)   return 出去一个返回值
    }, 
    // 给p对象身上增加/ 修改某个属性时调用
    set(target, propName, value) {
      console.log(`有人修改/增加了p身上的${propName}属性`, 更新界面);
      Reflect.set(target, propName, value)
    },

    deleteproperty(target, propName) {
      console.log(`有人删除了p身上的${propName}属性`, 更新界面);
      return Reflect.deleteProperty(target, value)    // 删除一个属性
    }
  })

  Proxy: 用到的是一个代理对象,   Reflect: 反射对象 (对立的一面)
 

猜你喜欢

转载自blog.csdn.net/weixin_45677987/article/details/123381268