vue3響應式原理


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  vue3兼容性只到ie11,如果監測到vue3無法兼容,會自動優雅降級到vue2
  <script>
    // vue3中的響應式原理,利用Proxy對象對數據攔截
    // 如何避免重復代理
    const toProxy = new WeakMap() //形如 obj:observed
    const toRow = new WeakMap() //形如 observed:obj


    function isObject(obj){
      return typeof obj === 'object' || obj === null
    }
    function reactive(obj){
      if(!isObject(obj)){
        return
      }

      // 查找緩存
      if(toProxy.has(obj)){
        return toProxy.get(obj)
      }
      // 傳入的obj就是代理對象,此時不用反復代理
      if(toRow.has(obj)){
        return obj
      }

      const observed = new Proxy(obj,{
        // 屬性的增刪改查都涉及到了
        get(target,key,receiver){
          // 優雅的獲取值
          const res = Reflect.get(target,key,receiver)
          console.log(`獲取${key}:${res}`);
          // 運行時遞歸,相比於初始化遞歸,性能較好
          return isObject(res) ? reactive(res) : res
        },
        set(target,key,val,receiver){
          // 返回bool
          const res = Reflect.set(target,key,val,receiver)
          console.log(`設置${key}:${res}`);
          return res
        },
        deleteProperty(target,key){
          const res = Reflect.deleteProperty(target,key)
          console.log(`刪除${key}`);
          return res
        },
      })

      // 緩存
      toProxy.set(obj,observed)
      toRow.set(observed,obj)

      return observed
    }

    const data = {foo:'foo',bar:{a:1},arr:[1,2,3]}
    const react = reactive(data)
    // 1獲取
    // react.foo
    // 2設置已存在屬性
    // react.foo = 'fooooooo'
    // 3設置不存在屬性
    // react.name = 'zhongwuhuang'
    // 4嵌套對象設置
    react.bar.a = 10
    react.bar.a
    // 操作數組
    // react.arr[0] = 10
    // react.arr

    // 時候是否緩存成功
    // console.log(react === reactive(data));
    


  </script>
</body>
</html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM