用Proxy实现watch监听对象、用Proxy代理函数可添加额外逻辑

使用Proxy实现watch监听对象

  • 手写一个简单的watch函数用来监听某个数据的变化,比如Object
  • 我们来写一个简单的形式的watch
  • 形式:watch(target, (newVal, oldVal)=>{ })
  • target表示监听的对象newVal, oldVal自然就是新值和旧值
  • 如下完整代码:




    
    
    Document



    
    



上述代码不考虑深层次对象,若是深层次,那就是递归操作即可,不赘述

注意,vue3的原始数据,也是经过代理后,就不用了

如下代码:



let initVal = '我是初始值'
const vvv = ref(initVal)
  • 当我们在输入框中输入内容的时候,vvv的值,会发生变化
  • 但是初始值initVal的值,是不会再变化的
  • 即 initVal 只是使用了一次,类似上边的代码

defineProperty监听形式

  • 比如使用Object.defineProperty去监听某个对象的某个属性值变化
  • 这种和上面的区别就是原始对象,依旧及时使用
  • 如下:




    
    
    Document



    
    




  • 实际上,Proxy功能更为强大,还可以代理函数,实现功能的重写
  • 就类似于继承后的新加功能
  • 如下:

用Proxy代理函数可添加额外逻辑

假设有一个函数,用来求和,求1~n的和,如下:

 // 求1~n的累加的和
function sum(n) {
    let result = 0
    for (let i = 0; i < n; i++) {
        result = result + i + 1
    }
    return result
}
  • 某些情况下,我们不能修改这个函数
  • 并且也不方便重写这个函数
  • 我们得在这个函数中,添加一些功能
  • 比如:当前的函数返回的是1~n的累加值
  • 要修改成返回一个数组,数组的第一项是1~n的累加值,数组的第2项是要返回1~n的累乘值
  • 那么,这个时候,我们就可以Proxy来代理这个函数,去加功能
  • 如下:




    
    
    Document



    


  • 上述案例中,我们也可以去新增逻辑代理函数
  • 去计算函数执行时间
  • 如下:

这样我们就新增了一个及时

Proxy的一种角度的理解

  • Vue3.0中通过Proxy来替换原本的Object.defineProperty来实现数据响应式
  • Proxy 是 ES6 中新增的功能,它可以用来自定义对象中的操作。
  • tips: ES6是2015年6月发布的
let p = new Proxy(target, handler)

target 代表需要添加代理的对象,handler 用来自定义对象中的操作,比如可以用来自定义 set 或者 get 函数。

当然,还有别的语法:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Refer...

实际上,功能超级强大

如果需要实现一个 Vue 中的响应式,需要在 get 中收集依赖,在 set 派发更新,之所以 Vue3.0 要使用 Proxy 替换原本的 API 原因在于 Proxy 无需一层层递归为每个属性添加代理,一次即可完成以上操作,性能上更好,并且原本的实现有一些数据更新不能监听到,但是 Proxy 可以完美监听到任何方式的数据改变,唯一缺陷就是浏览器的兼容性不好。
  • 实际上,笔者认为,Proxy的兼容性已经不错了
  • 毕竟是2015年发布的ES6里面的东西(现在是2024年了)
  • 可是啊,IE11是微软在2013年10月17日发布的浏览器
  • 所以,2013年还没ES6呢,也就没有Proxy
  • 所以,vue3不兼容IE11,是因为IE11没法用ES6里面的Proxy
  • 历史原因...
A good memory is better than a bad pen. Record it down...

你可能感兴趣的:(vue3javascript)