中職學(xué)校招生網(wǎng)_55px.com.cn

前端培訓(xùn):Vue3計算屬性比普通函數(shù)好的原因

2025-09-12 03:38:25

原標題:前端訓(xùn)練:Vue3的計算性質(zhì)優(yōu)于普通函數(shù)的原因

寫在前面

屬性計算是Vue開發(fā)中非常實用的API,允許用戶自定義一個計算方法,然后根據(jù)一些依賴的響應(yīng)數(shù)據(jù)計算出新的值并返回。當(dāng)依賴關(guān)系發(fā)生變化時,計算出的屬性會自動重新計算得到一個新值,使用起來很方便。我們看到計算屬性本質(zhì)上是依賴關(guān)系的計算,為什么不直接使用函數(shù)呢?Vue3中的計算屬性是如何實現(xiàn)的?

屬性計算

先舉個簡單的例子。我們看到設(shè)置計算屬性addOne后,直接改變addOne.value的值會出錯?!娟P(guān)注尚硅谷,輕松學(xué)起】只有改變原來的value count.value,才能不出錯誤。這是因為:

如果傳遞給computed的是一個函數(shù),那就是一個getter函數(shù),只能獲取它的值,而不能直接修改它 在getter函數(shù)中,根據(jù)響應(yīng)式對象重新計算出新值,叫做計算屬性,這個響應(yīng)式對象叫做計算屬性的依賴

const count = ref(1);

const addOne = computed(()= > count . value+1);

console . log(addone . value);//2

addone . value++;//錯誤

count . value++;

console . log(count . value);//3

那么,應(yīng)該如何修改addOne.value值呢?也就是說,在computed中設(shè)置set函數(shù)來定制值。

const count = ref(1);

const addOne = computed({

get:()=>count.value+1,

set:val=>count.value=val-1

});

addone . value = 1;

console . log(count . value);//0

我們研究源代碼:

導(dǎo)出函數(shù)計算(

getter options:computed getter | writable computed options

) {

let getter: ComputedGetter

let setter: ComputedSetter

//如果傳入函數(shù),則表示只讀計算。

if(is function(getter options)){

getter = getterOrOptions

setter = __DEV__

?() => {

console.warn('寫操作失敗:計算值是只讀的')

}

:NOOP

} else {

//不是方法說明,而是自定義的getter setter。

getter = getterOrOptions.get

setter = getterOrOptions.set

}

let dirty = true

let值:T

讓computed: ComputedRef

//創(chuàng)建效果。當(dāng)我們看效果的源代碼時,我們知道傳入的懶惰意味著它不會被立即執(zhí)行。當(dāng)計算的上游依賴性改變時,觸發(fā)器轉(zhuǎn)輪效應(yīng)將被給予優(yōu)先權(quán)。當(dāng)調(diào)度器意味著效果觸發(fā)時,將調(diào)用調(diào)度器而不是直接調(diào)用效果。

const runner = effect(getter,{

懶:真的,

//將效果標記為已計算,以便它在觸發(fā)期間獲得優(yōu)先級

computed: true,

調(diào)度程序:()=> {

//觸發(fā)更新時將dirty設(shè)置為true,不會立即更新。

if(!骯臟){

臟=真

trigger(computed,TriggerOpTypes。設(shè)置,“值”)

}

}

})

//構(gòu)造一個計算返回

計算的= {

__v_isRef: true,

//可以停止如此計算的暴露效果

效果:跑步者,

獲取值(){

// dirty為true,在進行g(shù)et操作時,執(zhí)行effect以獲取剛剛值。

//

如果(臟){

value = runner()

臟=假

}

// dirty為false,表示值沒有更新,直接返回。

track(computed,TrackOpTypes。獲取,'值')

返回值

},

設(shè)定值(新值:T) {

setter(新值)

}

}如任何

計算的回報

}

計算的計算屬性有兩個特征:

延時計算:只有當(dāng)我們訪問計算屬性時,真正運行computed getter函數(shù)計算 緩存:它的內(nèi)部會緩存上次的計算結(jié)果value,而只有dirty為true時才會重新計算,如果訪問計算屬性時dirty為false,那么直接返回這個value

然后,計算屬性的好處是,只要依賴關(guān)系不變,就可以使用緩存的值,而不是atguigu每次再次渲染組件時執(zhí)行函數(shù)進行計算。

作為嵌套計算的一個小例子,我們可以看到,對于addOne,它收集的依賴是組件副作用渲染函數(shù),而對于count,它收集的依賴是addTwo內(nèi)部的runner函數(shù)。當(dāng)我們修改計數(shù)值時,我們將分發(fā)通知。首先,在addOne中運行setter函數(shù)。此時addOne中的dirty值變?yōu)閠rue,然后觸發(fā)函數(shù)再次分發(fā)通知。然后運行addTwo中的setter函數(shù),再將addTwo中的dirty值設(shè)置為true;當(dāng)我們再次訪問addTwo中的值時,我們發(fā)現(xiàn)如果dirty為true,我們將執(zhí)行addTwo的計算函數(shù),然后我們將執(zhí)行addOne.value+1,然后在addOne的計算函數(shù)中執(zhí)行count.value+1。這樣,最終打印出來的值就是2。

const count = ref(0);

const addOne = computed(()=>{

返回count . value+1;//1

})

const addTwo = computed(()=>{

返回addone . value+1;//2

})

console . log(add two . value);//2

得益于computed計算屬性的巧妙設(shè)計,無論嵌套多少層,都能正常運行。

從“vue”導(dǎo)入{ref,computed };

從“@vue/reactivity”導(dǎo)入{ effect };

const count = ref(0);

const addOne = computed(()=>{

返回count . value+1;

})

effect(()= > console . log(addone . value+count . value))

函數(shù)add(){

count . value++;

}

add();

我們看到上面代碼的最終輸出是:1 3 3。

我們比較好次執(zhí)行addOne的computed計算屬性時,count.value的值還是0,而addOne.value的值是1,會觸發(fā)并執(zhí)行效果,打印出來的結(jié)果還是1。然后在執(zhí)行add()函數(shù)時,會修改count.value的值,觸發(fā)執(zhí)行效果函數(shù),因為addOne也是效果的依賴,addOne的runners函數(shù)也是count.value的依賴,count.value值的修改會執(zhí)行runners函數(shù),再次執(zhí)行addOne的依賴,然后觸發(fā)效果函數(shù),所以輸出兩次3。

計算函數(shù)返回的對象實際上劫持了value屬性的getter和setter,但是為什么我們在組件的模板中訪問一個計算屬性變量,而沒有手動添加。價值?

推薦閱讀:

前端培訓(xùn):Vue3語法糖詳解分享

Web前端培訓(xùn):Vue3面試考點分享

前端培訓(xùn):Vue3增加了公共方法和用途

Vue3“愛”CSS變量,結(jié)果會如何返回搜狐,多看?

負責(zé)編輯:

文章標題:前端培訓(xùn):Vue3計算屬性比普通函數(shù)好的原因

本文地址:http://balticsea-crewing.com/show-91049.html

本文由合作方發(fā)布,不代表中職學(xué)校招生網(wǎng)_55px.com.cn立場,轉(zhuǎn)載聯(lián)系作者并注明出處:中職學(xué)校招生網(wǎng)_55px.com.cn

免責(zé)聲明:本文僅代表文章作者的個人觀點,與本站無關(guān)。其原創(chuàng)性、真實性以及文中陳述文字和內(nèi)容未經(jīng)本站證實,請讀者僅作參考,并自行核實相關(guān)內(nèi)容。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請聯(lián)系郵箱:dashenkeji8@163.com,我們將在第 一 時 間進行核實處理。軟文/友鏈/推廣/廣告合作也可以聯(lián)系我。
展開全文

獲取招生簡章