vue3.0中的computed寫法
vue3.0 computed寫法
用computed計(jì)算屬性之前別忘了引入
使用完畢別忘了導(dǎo)出
computed里面還有兩個(gè)方法:get和set
- get方法:
結(jié)果:
get方法是讀取數(shù)據(jù)時(shí)候調(diào)用的,監(jiān)測(cè)到數(shù)據(jù)變化以后就自動(dòng)執(zhí)行:
結(jié)果:
點(diǎn)擊以后:
說明get在程序運(yùn)行時(shí)自動(dòng)調(diào)用,后面監(jiān)測(cè)到數(shù)據(jù)變化就再次調(diào)用
我們改一下代碼:
點(diǎn)擊前結(jié)果:
點(diǎn)擊后結(jié)果:
所以我們能得出: 點(diǎn)擊button以后,執(zhí)行到plusOne.value = 2
時(shí)候,相當(dāng)于調(diào)用了:
// 其中參數(shù)val就是修改的值2 set: val => { console.log('executing function set') return count.value = val - 1 }
所以現(xiàn)在count的值為2-1=1,這樣的值改變引起set方法的注意,被監(jiān)測(cè)到了,所以繼續(xù)執(zhí)行:
get: () => { console.log('executing function get') return count.value + 1 }
這樣count的值變成1+1 = 2
所以最后顯示2
vue3.0 computed的使用及其注意點(diǎn)
為什么使用
當(dāng)我們不想在template的html元素上寫很長的js邏輯時(shí),我們就會(huì)想使用計(jì)算屬性computed
使用
computed
傳入一個(gè) getter 函數(shù),返回一個(gè)默認(rèn)不可手動(dòng)修改的 ref 對(duì)象。
取自官網(wǎng):https://vue3js.cn/reactivity/computed.html#computed
const count = ref(1) const plusOne = computed(() => count.value + 1) console.log(plusOne.value) // 2 plusOne.value++ // 錯(cuò)誤! // 或者傳入一個(gè)擁有 get 和 set 函數(shù)的對(duì)象,創(chuàng)建一個(gè)可手動(dòng)修改的計(jì)算狀態(tài)。 const count = ref(1) const plusOne = computed({ ? get: () => count.value + 1, ? set: (val) => { ? ? count.value = val - 1 ? }, }) plusOne.value = 1 console.log(count.value) // 0 // 更多文檔: https://vue3js.cn/vue-composition-api/#computed
正文
計(jì)算屬性,可能會(huì)依賴其他 reactive 的值,同時(shí)會(huì)延遲和緩存計(jì)算值
export function computed<T>( ? getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T> ) { ? let getter: ComputedGetter<T> ? let setter: ComputedSetter<T> ? // 如果傳入是 function 說明是只讀 computed ? if (isFunction(getterOrOptions)) { ? ? getter = getterOrOptions ? ? setter = __DEV__ ? ? ? ? () => { ? ? ? ? ? console.warn('Write operation failed: computed value is readonly') ? ? ? ? } ? ? ? : NOOP ? } else { ? ? // 不是方法說明是自定義的 getter setter? ? ? getter = getterOrOptions.get ? ? setter = getterOrOptions.set ? } ? let dirty = true ? let value: T ? let computed: ComputedRef<T> ? // 創(chuàng)建 effect, 我們?cè)诳?effect 源碼時(shí)知道了傳入 lazy 代表不會(huì)立即執(zhí)行,computed 表明 computed 上游依賴改變的時(shí)候,會(huì)優(yōu)先 trigger runner effect, scheduler 表示 effect trigger 的時(shí)候會(huì)調(diào)用 scheduler 而不是直接調(diào)用 effect ? const runner = effect(getter, { ? ? lazy: true, ? ? // mark effect as computed so that it gets priority during trigger ? ? computed: true, ? ? scheduler: () => { ? ? ? // 在觸發(fā)更新時(shí)把dirty置為true, 不會(huì)立即更新? ? ? ? if (!dirty) { ? ? ? ? dirty = true ? ? ? ? trigger(computed, TriggerOpTypes.SET, 'value') ? ? ? } ? ? } ? }) ? // 構(gòu)造一個(gè) computed 返回 ? computed = { ? ? __v_isRef: true, ? ? // expose effect so computed can be stopped ? ? effect: runner, ? ? get value() { ? ? ? // dirty為ture, get操作時(shí),執(zhí)行effect獲取最新值 ? ? ? //? ? ? ? if (dirty) { ? ? ? ? value = runner() ? ? ? ? dirty = false ? ? ? } ? ? ? // dirty為false, 表示值未更新,直接返回? ? ? ? track(computed, TrackOpTypes.GET, 'value') ? ? ? return value ? ? }, ? ? set value(newValue: T) { ? ? ? setter(newValue) ? ? } ? } as any ? return computed }
注意事項(xiàng)
如果存在計(jì)算屬性依賴其他異步或者props傳進(jìn)的屬性,再通過state.xxx獲取最新屬性值進(jìn)行判斷,那么就必須寫在getter回調(diào)里,例如:
const haveFile = computed(() => state.jobInfo.fileName ? state.jobInfo.fileName.includes('http') : false); const permitProduct = computed(() => !state.isPower || state.isDqcFinish); const permitDownl = computed(() => !state.isPower || !haveFile.value);
我們可以看到permitProduct 和permitDownl 都依賴state.isPower這個(gè)變量值,且該變量寫在watch監(jiān)聽中,隨時(shí)可能改變,因此,我們console.log寫在permitDownl 變量的下一行,可能看不到最新結(jié)果的打?。?/p>
const haveFile = computed(() => state.jobInfo.fileName ? state.jobInfo.fileName.includes('http') : false); const permitProduct = computed(() => !state.isPower || state.isDqcFinish); const permitDownl = computed(() => !state.isPower || !haveFile.value); console.log('state.isPower ===>', state.isPower);
正確的做法,應(yīng)該是寫在getter回調(diào)里:
const haveFile = computed(() => state.jobInfo.fileName ? state.jobInfo.fileName.includes('http') : false); const permitProduct = computed(() => !state.isPower || state.isDqcFinish); const permitDownl = computed(() => { ?? ?console.log('state.isPower ===>', state.isPower); // 此時(shí)可以獲得最新值 ?? ?return !state.isPower || !haveFile.value; });
并且要注意的一點(diǎn)是,如果當(dāng)前計(jì)算屬性依賴其他計(jì)算屬性,例如上面所寫的permitDownl 依賴于 haveFile,這時(shí),寫法就必須是haveFile.value而非haveFile
計(jì)算屬性獲取值在非template區(qū)域,而是在js區(qū)域內(nèi),則必須使用propname.value去獲取值!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue使用原生js實(shí)現(xiàn)滾動(dòng)頁面跟蹤導(dǎo)航高亮的示例代碼
這篇文章主要介紹了vue使用原生js實(shí)現(xiàn)滾動(dòng)頁面跟蹤導(dǎo)航高亮的示例代碼,滾動(dòng)頁面指定區(qū)域?qū)Ш礁吡痢P【幱X得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10Vue watch響應(yīng)數(shù)據(jù)實(shí)現(xiàn)方法解析
這篇文章主要介紹了Vue watch響應(yīng)數(shù)據(jù)實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07vue.js 實(shí)現(xiàn)輸入框動(dòng)態(tài)添加功能
這篇文章主要介紹了vue.js 實(shí)現(xiàn)輸入框動(dòng)態(tài)添加功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-06-06關(guān)于el-table表格組件中插槽scope.row的使用方式
這篇文章主要介紹了關(guān)于el-table表格組件中插槽scope.row的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08vue router 跳轉(zhuǎn)時(shí)打開新頁面的示例方法
這篇文章主要介紹了vue router 跳轉(zhuǎn)時(shí)打開新頁面的示例方法,本文通過示例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07vue項(xiàng)目index.html中使用環(huán)境變量的代碼示例
在Vue3中使用環(huán)境變量的方式與Vue2基本相同,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目index.html中使用環(huán)境變量的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02使用Vue3進(jìn)行數(shù)據(jù)綁定及顯示列表數(shù)據(jù)
這篇文章主要介紹了使用Vue3進(jìn)行數(shù)據(jù)綁定及顯示列表數(shù)據(jù),整篇文章圍繞Vue3進(jìn)行數(shù)據(jù)綁定及顯示列表數(shù)據(jù)的想換自來哦展開內(nèi)容,需要的小伙伴可以參考一下2021-10-10Vue項(xiàng)目優(yōu)化打包之前端必備加分項(xiàng)
相信現(xiàn)在很多人都是用Vue做過了各種項(xiàng)目,但是項(xiàng)目代碼做完和上線并不代表這結(jié)束,還有上線以后的優(yōu)化也是很重要的一點(diǎn),這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目優(yōu)化打包的相關(guān)資料,需要的朋友可以參考下2021-09-09