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

Vue3實現(xiàn)計算屬性的代碼詳解

 更新時間:2023年07月31日 10:40:55   作者:護(hù)國神蛙  
計算屬性對于前端開發(fā)來說算是經(jīng)常使用的一個能力了,本文將從代碼層面來給大家介紹下Vue3是如何實現(xiàn)計算屬性的,需要的朋友可以參考下

代碼解釋

import { ReactiveEffect } from "./effect"
class computedImpl {
    private _fn: any
    private stop: boolean = true
    private _value: any
    private _effect: any
    constructor(fn) {
        this._fn = fn // (1)
        this._effect = new ReactiveEffect(fn, () => { // (2)
            if (!this.stop) {
                this.stop = true
            }
        })
    }
    get value() {
        if(this.stop) {
            this.stop = false
            this._value = this._effect.run()
        }
        return this._value
    }
}
export function computed(fn) {
    return new computedImpl(fn)
}

可以看到代碼其實很簡單,創(chuàng)建了一個computedImpl類,這個類接收一個函數(shù)作為其參數(shù),最下面將實例化的computedImpl對象拋出即可。

看著很簡單,那我們來介紹下計算屬性在這個類里面做了什么?

一、實例化的時候會將傳進(jìn)去函數(shù)緩存起來(1)

二、創(chuàng)建一個ReactiveEffect對象,將傳入的fn作為參數(shù)傳入,第二個參數(shù)處接收一個scheduler函數(shù)(2)

() => { 
    if (!this.stop) {
        this.stop = true
    }
}

這里介紹一下這一步的作用:

Vue3 有一個ReactiveEffect這樣的類,接收兩個參數(shù),一個是默認(rèn)函數(shù),另一個是scheduler函數(shù)。

創(chuàng)建這樣的類有什么作用呢?首先我們知道傳入的函數(shù)里面肯定有響應(yīng)式的數(shù)據(jù),因為計算屬性的作用是當(dāng)響應(yīng)式數(shù)據(jù)更新時重新計算我們傳入的計算屬性函數(shù)。,意味著我們要給給這些響應(yīng)式數(shù)據(jù)去收集一個依賴,用于告訴我們計算屬性響應(yīng)式數(shù)據(jù)是否有發(fā)生變動。

那我們Vue3是怎么去收集依賴的呢?那就不得不提到ReactiveEffect了,實例化ReactiveEffect對象有一個run函數(shù),當(dāng)我們執(zhí)行run函數(shù)的時候會執(zhí)行一遍我們傳入的fn并且將自身指向一個全局變量activeEffect,當(dāng)我們響應(yīng)式數(shù)據(jù)發(fā)生取值操作的時候就會去收集依賴,就是去判斷activeEffect是否存在,如果存在收集起來。

當(dāng)響應(yīng)式數(shù)據(jù)發(fā)生set操作的時候,就會去觸發(fā)依賴,那么我們之前存進(jìn)去的實例化ReactiveEffect對象就會被拿出來執(zhí)行,這樣我們就可以知道數(shù)據(jù)發(fā)生了改變,默認(rèn)情況下會執(zhí)行ReactiveEffect傳進(jìn)的默認(rèn)函數(shù),但是如果scheduler函數(shù)存在那就會執(zhí)行scheduler函數(shù)。

三、計算屬性函數(shù)執(zhí)行與緩存

上面已經(jīng)知道如何實現(xiàn)依賴收集的了,那么講解下函數(shù)執(zhí)行和緩存的實現(xiàn)。

因為我們已經(jīng)創(chuàng)建了一個實例化ReactiveEffect對象,在執(zhí)行這個對象的run函數(shù)時會執(zhí)行我們傳入的函數(shù),所以當(dāng)我們get Value的時候就會執(zhí)行一遍函數(shù),因為執(zhí)行函數(shù)的時候會,觸發(fā)響應(yīng)式對象的取值操作,ReactiveEffect對象被存儲到依賴中,并且返回函數(shù)的計算結(jié)果。

這樣我們每次執(zhí)行g(shù)et Value都會執(zhí)行函數(shù)拿到函數(shù)結(jié)果。因為computed會有緩存功能,所以這里又設(shè)置了一個_value和stop用在結(jié)果緩存和開關(guān),默認(rèn)get Value操作走一遍stop的判斷函數(shù)執(zhí)行完之后關(guān)閉開關(guān),防止每次執(zhí)行都會走一遍函數(shù),然后將函數(shù)結(jié)果緩存到_value中,下次直接拿_value就行

if(this.stop) {
    this.stop = false
    this._value = this._effect.run()
}
return this._value

上面的代碼可以看到我們這個開關(guān)一關(guān)閉就不會打開了,那我們豈不是每次都會拿到老的值?
回到上面的實例化ReactiveEffect對象中,這里傳入了一個scheduler函數(shù)。

() => { 
    if (!this.stop) {
        this.stop = true
    }
}

當(dāng)響應(yīng)式數(shù)據(jù)發(fā)生改變的時候scheduler函數(shù)執(zhí)行,stop開關(guān)打開,那我們下一次執(zhí)行g(shù)et Value就會重新執(zhí)行函數(shù)更新計算屬性的結(jié)果

總結(jié)

在computed實際上是返回了一個實例化的對象,這個對象在實例化的時候接收了一個參數(shù)就是computed內(nèi)部的回調(diào)。

因為computed是緩存的,所以返回的實例化對象中有一個get方法,取值的時候就會將傳入的回調(diào)給執(zhí)行了,并且把結(jié)果設(shè)置為實例化對象的內(nèi)部屬性,并返回出去。

所以computed在取值的時候?qū)嶋H上就讀取了存在在對象中的回調(diào)函數(shù)的執(zhí)行結(jié)果。

因為computed會緩存所以在執(zhí)行g(shù)et方法的時候會做一個開關(guān),比如說lazy默認(rèn)為true,只有當(dāng)lazy為true才能執(zhí)行回調(diào)函數(shù),當(dāng)函數(shù)執(zhí)行完lazy改成false,所以后續(xù)的取值操作都不執(zhí)行函數(shù),實現(xiàn)了緩存的功能。

因為如果computed里面的響應(yīng)式對象如果發(fā)生了改變,computed的結(jié)果是需要更新的,所以需要對computed里面的響應(yīng)式對象進(jìn)行一個依賴設(shè)置。

vue在進(jìn)行依賴收集的時候會用一個全局的變量去存儲回調(diào)函數(shù),在響應(yīng)式對象get操作的時候就會判斷這個全局變量是否存在,如果存在則加到依賴中,后續(xù)set操作的時候就拿這些存儲的依賴處理執(zhí)行。

所以computed在實例化對象的時候,會構(gòu)造一個這樣一個全局變量然后里面的回調(diào)函數(shù)的作用是如果執(zhí)行l(wèi)azy置為true,即開關(guān)打開。

然后因為去取值的時候會執(zhí)行一次函數(shù),所以響應(yīng)式對象get被觸發(fā),把lazy置為true的回調(diào)存入依賴中,下次響應(yīng)式對象更新值即set的時候,computed返回的實例對象內(nèi)部的開關(guān)就會被打開了。

所以我們下一次執(zhí)行computed的value的時候,因為開關(guān)是開的所以會重新執(zhí)行一遍函數(shù)并更新實例化對象的值,然后開關(guān)關(guān)上緩存起來,返回新的值。

以上就是Vue3實現(xiàn)計算屬性的代碼詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue3計算屬性的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于vue里頁面的緩存詳解

    關(guān)于vue里頁面的緩存詳解

    今天小編就為大家分享一篇關(guān)于vue里頁面的緩存詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • vue項目報錯:Missing?script:"serve"的解決辦法

    vue項目報錯:Missing?script:"serve"的解決辦法

    這篇文章主要給大家介紹了關(guān)于vue項目報錯:Missing?script:"serve"的解決辦法,"missing script: serve"是一個錯誤信息,意味著在執(zhí)行啟動腳本時,找不到名為"serve"的腳本,需要的朋友可以參考下
    2023-11-11
  • Vue使用Props實現(xiàn)組件數(shù)據(jù)交互的示例代碼

    Vue使用Props實現(xiàn)組件數(shù)據(jù)交互的示例代碼

    在Vue中,組件的props屬性用于定義組件可以接收的外部數(shù)據(jù),這些數(shù)據(jù)來自父組件并傳遞給子組件,本文給大家介紹了Vue使用Props實現(xiàn)組件數(shù)據(jù)交互,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-06-06
  • Vue3+vuedraggable實現(xiàn)動態(tài)配置頁面

    Vue3+vuedraggable實現(xiàn)動態(tài)配置頁面

    這篇文章主要為大家詳細(xì)介紹了Vue3如何利用vuedraggable實現(xiàn)動態(tài)配置頁面,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的可以參考一下
    2023-12-12
  • Vue3 封裝 element-plus 圖標(biāo)選擇器實現(xiàn)步驟

    Vue3 封裝 element-plus 圖標(biāo)選擇器實現(xiàn)步驟

    這篇文章主要介紹了Vue3 封裝 element-plus 圖標(biāo)選擇器,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • vue3.0安裝element?plus依賴的過程

    vue3.0安裝element?plus依賴的過程

    這篇文章主要介紹了vue3.0安裝element?plus依賴的過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Vue + ts實現(xiàn)輪播插件的示例

    Vue + ts實現(xiàn)輪播插件的示例

    這篇文章主要介紹了Vue + ts實現(xiàn)輪播插件的示例,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2020-11-11
  • Vue中如何實現(xiàn)字符串換行

    Vue中如何實現(xiàn)字符串換行

    這篇文章主要介紹了Vue中如何實現(xiàn)字符串換行問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue-element中el-input輸入卡頓問題的解決

    Vue-element中el-input輸入卡頓問題的解決

    這篇文章主要介紹了Vue-element中el-input輸入卡頓問題的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue的v-if里實現(xiàn)調(diào)用函數(shù)

    vue的v-if里實現(xiàn)調(diào)用函數(shù)

    這篇文章主要介紹了vue的v-if里實現(xiàn)調(diào)用函數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評論

周口市| 鄂州市| 晴隆县| 长寿区| 承德县| 乌拉特后旗| 苏尼特左旗| 阜南县| 犍为县| 嘉禾县| 灵山县| 衡南县| 贵南县| 云南省| 莱芜市| 靖西县| 精河县| 隆德县| 宁明县| 安达市| 革吉县| 忻城县| 明光市| 新乐市| 成武县| 镇赉县| 当阳市| 米林县| 鄂伦春自治旗| 长岭县| 邛崃市| 阜城县| 湘潭县| 开原市| 洪湖市| 叙永县| 青神县| 太白县| 巴林左旗| 始兴县| 万山特区|