欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你深入理解Vue3響應(yīng)式原理

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

 響應(yīng)式原理

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

2.0的不足

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

reactive和effect的實(shí)現(xiàn)

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 的響應(yīng)式原理依賴了 Proxy 這個(gè)核心 API,通過 Proxy 可以劫持對(duì)象的某些操作。

effect track trigger

實(shí)現(xiàn)effect 副作用函數(shù)

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

 使用一個(gè)全局變量 active 收集當(dāng)前副作用函數(shù),并且初始化的時(shí)候調(diào)用一下

實(shí)現(xiàn)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í)行完成成后我們得到一個(gè)如下的數(shù)據(jù)結(jié)構(gòu) 

實(shí)現(xiàn)trigger

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

 當(dāng)我們進(jìn)行賦值的時(shí)候會(huì)調(diào)用 set 然后 觸發(fā)收集的副作用函數(shù)

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 添加這兩個(gè)方法

測(cè)試代碼

<!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>

遞歸實(shí)現(xiàn)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>

總結(jié)

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

相關(guān)文章

  • 基于Vue實(shí)現(xiàn)封裝一個(gè)虛擬列表組件

    基于Vue實(shí)現(xiàn)封裝一個(gè)虛擬列表組件

    正常情況下,我們對(duì)于數(shù)據(jù)都會(huì)分頁加載,最近項(xiàng)目中確實(shí)遇到了不能分頁的場(chǎng)景,如果不分頁,頁面渲染幾千條數(shù)據(jù)就會(huì)感知到卡頓,使用虛擬列表就勢(shì)在必行了。本文主要介紹了如何基于Vue實(shí)現(xiàn)封裝一個(gè)虛擬列表組件,感興趣的可以了解一下
    2023-03-03
  • vue devserver及其配置方法

    vue devserver及其配置方法

    這篇文章主要介紹了vue devserver及其配置方法,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • vue 微信授權(quán)登錄解決方案

    vue 微信授權(quán)登錄解決方案

    這篇文章主要介紹了vue 微信授權(quán)解決方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • vuex中的state使用及說明

    vuex中的state使用及說明

    這篇文章主要介紹了vuex中的state使用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • vue結(jié)合leaflet實(shí)現(xiàn)地圖放大鏡

    vue結(jié)合leaflet實(shí)現(xiàn)地圖放大鏡

    放大鏡在很多地方都可以使用的到,本文主要介紹了vue結(jié)合leaflet實(shí)現(xiàn)地圖放大鏡,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 詳解vue-cli開發(fā)環(huán)境跨域問題解決方案

    詳解vue-cli開發(fā)環(huán)境跨域問題解決方案

    本篇文章主要介紹了vue-cli開發(fā)環(huán)境跨域問題解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-06-06
  • Vue首頁界面加載優(yōu)化實(shí)現(xiàn)方法詳解

    Vue首頁界面加載優(yōu)化實(shí)現(xiàn)方法詳解

    如果你也遇到在 vue 應(yīng)用中,首頁加載資源過多,導(dǎo)致加載緩慢的問題,下面的方法也許能幫到你,主要的處理思想是:讓首頁多余的資源能在需要它的時(shí)候再加載
    2022-09-09
  • vue不用import直接調(diào)用實(shí)現(xiàn)接口api文件封裝

    vue不用import直接調(diào)用實(shí)現(xiàn)接口api文件封裝

    這篇文章主要為大家介紹了vue不用import直接調(diào)用實(shí)現(xiàn)接口api文件封裝,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • vue實(shí)現(xiàn)PC端分辨率適配操作

    vue實(shí)現(xiàn)PC端分辨率適配操作

    這篇文章主要介紹了vue實(shí)現(xiàn)PC端分辨率適配操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • VUE路由動(dòng)態(tài)加載實(shí)例代碼講解

    VUE路由動(dòng)態(tài)加載實(shí)例代碼講解

    在本文里小編給大家整理了關(guān)于VUE路由動(dòng)態(tài)加載實(shí)例代碼以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-08-08

最新評(píng)論