Code前端首页关于Code前端联系我们

vue3学习(一)响应式数据核心原理

terry 2年前 (2023-09-08) 阅读数 134 #Vue

比较vue2和vue3的响应能力

vue2 的回应

  • 核心:
  1. 对象:通过defineProperty
  2. 劫持(监控拦截)现有对象私有属性的读取和修改
  3. 数组:通过数组重写和数组更新,实现一系列元素更新方法来劫持元素修改
   Object.defineProperty(date,'count',{
            get(){},
            set()
        })
 

问题:

  • 如果直接在对象上使用天剑属性或者删除已有的属性,界面不会自动更新
  • 直接用下标替换元素来更新length,界面不会自动更新

vue3 的回应

  • 通过Proxy(代理)拦截对属性data的任何操作(13种),包括读、写、删除等...

  • 通过Reflect(反射)对相应的代理对象属性动态执行某些操作

  • 文档:
    developer.mozilla.org/zh-CN/docs/…
    developer.mozilla.org/zh-CN/docs/…

    以下是一些操作示例Proxy

new Proxy(data,{
         //拦截读取属性值
         get(target,prop){
             return Reflect.get(target,prop)
         },
         //拦截设置属性值或添加属性值
         set(target,prop,value){
             return Reflect.set(target,prop,value)
         },
         //拦截删除属性
         deleteProperty(trget,prop){
             return  Reflect.deleteProperty(trget,prop)
         }
     })
     Proxy.name='Loin'
 

获取属性值

image.pngimage.png

看看

写了什么

image.pngimage.png

为什么console.log(proxyUser.name)undefined
因为对象名不是通过反射对象反射出来的,所以我们在get方法中必须写 return Reflect.get(target,prop)

image.pngimage.png
这些是通过代理对象和反射对象实现的小效果,而且很容易理解

更改附加属性值

看下面的代码

image.pngimage.png

用户这样打印

image.pngimage.png

set方法

Proxy有三个属性targetpropval。对应的Reflect设置方法也有对应的三个属性。通过proxyUser更新名称,即可更新数据。
例如,如果要操作user上的属性girlFriend,可以直接定义并替换user.girlFriend.name

image.pngimage.png

image.pngimage.png

添加属性值是通过.gender属性完成的。无论是替换还是添加,每次操作都会调用一次set方法
###删除目标对象的属性值

image.pngimage.png

image.pngimage.png

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门