最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你深入理解Vue3響應式原理

 更新時間:2022年11月10日 09:44:36   作者:小滿zs  
響應式就是當對象本身(對象的增刪值)或者對象屬性(重新賦值)發(fā)生變化時,將會運行一些函數,最常見的就是render函數,下面這篇文章主要給大家介紹了關于Vue3響應式原理的相關資料,需要的朋友可以參考下

 響應式原理

Vue2 使用的是 Object.defineProperty  Vue3 使用的是 Proxy

2.0的不足

對象只能劫持 設置好的數據,新增的數據需要Vue.Set(xxx)  數組只能操作七種方法,修改某一項值無法劫持。

reactive和effect的實現

export const reactive = <T extends object>(target:T) => {
    return new Proxy(target,{
        get (target,key,receiver) {
          const res  = Reflect.get(target,key,receiver) as object
 
 
          return res
        },
        set (target,key,value,receiver) {
           const res = Reflect.set(target,key,value,receiver)
 
 
           return res
        }
    })
}

 Vue3 的響應式原理依賴了 Proxy 這個核心 API,通過 Proxy 可以劫持對象的某些操作。

effect track trigger

實現effect 副作用函數

let activeEffect;
export const effect = (fn:Function) => {
     const _effect = function () {
        activeEffect = _effect;
        fn()
     }
     _effect()
}

 使用一個全局變量 active 收集當前副作用函數,并且初始化的時候調用一下

實現track

const targetMap = new WeakMap()
export const track = (target,key) =>{
   let depsMap = targetMap.get(target)
   if(!depsMap){
       depsMap = new Map()
       targetMap.set(target,depsMap)
   }
   let deps = depsMap.get(key)
   if(!deps){
      deps = new Set()
      depsMap.set(key,deps)
   }
 
   deps.add(activeEffect)
}

執(zhí)行完成成后我們得到一個如下的數據結構 

實現trigger

export const trigger = (target,key) => {
   const depsMap = targetMap.get(target)
   const deps = depsMap.get(key)
   deps.forEach(effect=>effect())
}

 當我們進行賦值的時候會調用 set 然后 觸發(fā)收集的副作用函數

import {track,trigger} from './effect'
 
export const reactive = <T extends object>(target:T) => {
    return new Proxy(target,{
        get (target,key,receiver) {
          const res  = Reflect.get(target,key,receiver) as object
 
          track(target,key)
 
          return res
        },
        set (target,key,value,receiver) {
           const res = Reflect.set(target,key,value,receiver)
 
           trigger(target,key)
 
           return res
        }
    })
}

 給 reactive 添加這兩個方法

測試代碼

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
 
    <div id="app">
 
    </div>
 
    <script type="module">
        import { reactive } from './reactive.js'
        import { effect } from './effect.js'
        const user = reactive({
            name: "小滿",
            age: 18
        })
        effect(() => {
            document.querySelector('#app').innerText = `${user.name} - ${user.age}`
        })
 
        setTimeout(()=>{
            user.name = '大滿很厲害'
            setTimeout(()=>{
                user.age = '23'
            },1000)
        },2000)
 
    </script>
</body>
 
</html>

遞歸實現reactive

import { track, trigger } from './effect'
 
const isObject = (target) => target != null && typeof target == 'object'
 
export const reactive = <T extends object>(target: T) => {
    return new Proxy(target, {
        get(target, key, receiver) {
            const res = Reflect.get(target, key, receiver) as object
 
            track(target, key)
 
            if (isObject(res)) {
                return reactive(res)
            }
 
            return res
        },
        set(target, key, value, receiver) {
            const res = Reflect.set(target, key, value, receiver)
 
            trigger(target, key)
 
            return res
        }
    })
}
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
 
    <div id="app">
 
    </div>
 
    <script type="module">
        import { reactive } from './reactive.js'
        import { effect } from './effect.js'
        const user = reactive({
            name: "小滿",
            age: 18,
            foo:{
                bar:{
                    sss:123
                }
            }
        })
        effect(() => {
            document.querySelector('#app').innerText = `${user.name} - ${user.age}-${user.foo.bar.sss}`
        })
 
        setTimeout(()=>{
            user.name = '大滿很厲害'
            setTimeout(()=>{
                user.age = '23'
                setTimeout(()=>{
                    user.foo.bar.sss = 66666666
                },1000)
            },1000)
        },2000)
 
    </script>
</body>
 
</html>

總結

到此這篇關于Vue3響應式原理的文章就介紹到這了,更多相關Vue3響應式原理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • vue-cli3.0如何使用prerender-spa-plugin插件預渲染

    vue-cli3.0如何使用prerender-spa-plugin插件預渲染

    這篇文章主要介紹了vue-cli3.0如何使用prerender-spa-plugin插件預渲染,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 一文詳解Vue響應式數據的原理

    一文詳解Vue響應式數據的原理

    在vue2的響應式中,存在著添加屬性、刪除屬性、以及通過下標修改數組,但頁面不會自動更新的問題,而這些問題在vue3中都得以解決,本文就給大家詳細的介紹一下Vue響應式數據原理,感興趣的小伙伴跟著小編一起來看看吧
    2023-08-08
  • vue.js實現請求數據的方法示例

    vue.js實現請求數據的方法示例

    這篇文章主要給大家介紹了vue.js實現請求數據的方法示例,文中分別介紹了vue1.0和vue2.0的示例方法,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • vue中的router-view組件的使用教程

    vue中的router-view組件的使用教程

    這篇文章主要介紹了vue中的router-view組件的使用教程,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-10-10
  • Javascript對象及Proxy工作原理詳解

    Javascript對象及Proxy工作原理詳解

    這篇文章主要為大家介紹了Javascript對象及Proxy工作原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Vue組件通信之父傳子與子傳父深入探究

    Vue組件通信之父傳子與子傳父深入探究

    對于vue來說,組件之間的消息傳遞是非常重要的,用vue可以是要組件復用的,而組件實例的作用域是相互獨立,這意味著不同組件之間的數據無法互相引用,一般來說,組件之間可以有幾種關系,下面是我對組件之間消息傳遞的常用方式的總結
    2022-12-12
  • vue.js 動態(tài)組件詳解

    vue.js 動態(tài)組件詳解

    這篇文章主要介紹了vue.js 動態(tài)組件詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-09-09
  • vue組件生命周期鉤子使用示例詳解

    vue組件生命周期鉤子使用示例詳解

    這篇文章主要為大家介紹了vue組件生命周期鉤子使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • vue中使用詞云圖的實現示例

    vue中使用詞云圖的實現示例

    本文主要介紹了vue中使用詞云圖的實現示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • SpringBoot實現全局和局部跨域的兩種方式

    SpringBoot實現全局和局部跨域的兩種方式

    本文主要介紹了SpringBoot實現全局和局部跨域的兩種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01

最新評論

依兰县| 灌阳县| 茂名市| 玛曲县| 峨眉山市| 镇江市| 时尚| 麦盖提县| 东丰县| 印江| 濮阳市| 观塘区| 京山县| 永寿县| 木里| 若羌县| 宁晋县| 方正县| 阿拉善右旗| 邵武市| 丰县| 肥乡县| 嵩明县| 宜兰县| 南木林县| 宁河县| 中山市| 舒城县| 高碑店市| 申扎县| 巧家县| 武川县| 桃江县| 东丽区| 泰兴市| 柯坪县| 台北市| 鹿泉市| 天祝| 肥乡县| 渝中区|