vue計(jì)算屬性computed--getter和setter用法
計(jì)算屬性computed和方法methods的區(qū)別
計(jì)算屬性本質(zhì)上是包含getter和setter的方法
當(dāng)獲取計(jì)算屬性時(shí),實(shí)際上是在調(diào)用計(jì)算屬性的getter方法。vue會(huì)收集計(jì)算屬性的依賴,并緩存計(jì)算屬性的返回結(jié)果。只有當(dāng)依賴變化后才會(huì)重新進(jìn)行計(jì)算。
方法沒(méi)有緩存,每次調(diào)用方法都會(huì)導(dǎo)致重新執(zhí)行。
計(jì)算屬性的getter和setter參數(shù)固定,getter沒(méi)有參數(shù),setter只有一個(gè)參數(shù)。而方法的參數(shù)不限。
由于有以上的這些區(qū)別,因此計(jì)算屬性通常是根據(jù)已有數(shù)據(jù)得到其他數(shù)據(jù),并在得到數(shù)據(jù)的過(guò)程中不建議使用異步、當(dāng)前時(shí)間、隨機(jī)數(shù)等副作用操作。
實(shí)際上,他們最重要的區(qū)別是含義上的區(qū)別。計(jì)算屬性含義上也是一個(gè)數(shù)據(jù),可以讀取也可以賦值;方法含義上是一個(gè)操作,用于處理一些事情。
計(jì)算屬性的完整寫(xiě)法
computed: { propsName: { a:['aavsx'], get(){ return this.a; }, set(val){ this.a = val } }, }
注:
1.get方法是當(dāng)屬性被讀取時(shí)觸發(fā),在計(jì)算屬性中,如果計(jì)算屬性依賴沒(méi)有發(fā)生改變(例子中this.a就是計(jì)算屬性的依賴,只要this.a不發(fā)生改變,它就不會(huì)再次調(diào)用get方法),get只會(huì)調(diào)用一次,并且會(huì)將返回結(jié)果緩存起來(lái)。
2.get方法必須需要一個(gè)返回值,否者會(huì)報(bào)出以下錯(cuò)誤:
3.如果set方法沒(méi)有改變get方法中的依賴(this.a),則get方法不會(huì)再次調(diào)用,而是直接使用緩存值
<template> <div> {{propsName = 'add'}} //結(jié)果是add {{propsName}}//結(jié)果是 a ,以為set方法沒(méi)有改變this.a這個(gè)依賴 </div> </template> <script> export default { data(){ return { a:'a', b:'b' } }, computed: { propsName: { get(){ return this.a }, set(val){ this.b = val } }, } } </script>
一般情況下,計(jì)算屬性只使用getter方法,所以計(jì)算屬性可以簡(jiǎn)寫(xiě)為:
computed: { propName(){ // getter //必須要有返回值 } }
vue3計(jì)算屬性computed實(shí)現(xiàn)原理
computed實(shí)現(xiàn)原理
computed特性
computed可以傳入一個(gè)函數(shù),也可以傳入一個(gè)對(duì)象(帶有g(shù)et和set方法),計(jì)算屬性返回一個(gè)計(jì)算值,該值通過(guò)value屬性訪問(wèn),當(dāng)參與計(jì)算的數(shù)據(jù)發(fā)生改變,則重新計(jì)算,不發(fā)生改變,則直接返回之前緩存的值
render 只執(zhí)行了一次
const { effect, reactive,computed } = VueReactivity const state = reactive({ firstName:'s', lastName:'x' }) let fullName = computed(()=>{ console.log('runner') return state.firstName + state.lastName }) console.log(fullName.value) console.log(fullName.value) console.log(fullName.value)
計(jì)算屬性返回值可以作為屬性參與effect更新
const { effect, reactive,computed } = VueReactivity const state = reactive({ firstName:'s', lastName:'x' }) let fullName = computed({ get(){ return state.firstName + state.lastName }, set(value){ state.lastName = value } }) fullName.value = 100 effect(()=>{ app.innerHTML = fullName.value }) setTimeout(()=>{ state.firstName = 'x' },1000)
實(shí)現(xiàn)思路
導(dǎo)出一個(gè)computed函數(shù),函數(shù)內(nèi)部有兩個(gè)變量getter、setter
函數(shù)傳入一個(gè)對(duì)象或者函數(shù)。
如果是函數(shù),則將該函數(shù)賦值給getter,setter賦值為一個(gè)報(bào)錯(cuò)函數(shù)(即拋出錯(cuò)誤)
如果是對(duì)象,則將其get和set分別賦值給getter和setter
創(chuàng)建computedRefImpl類,有兩個(gè)形參(getter、setter),在computer函數(shù)中實(shí)例化并返回該類
類中在實(shí)例的constructor構(gòu)造器中通過(guò)實(shí)例化ReactiveEffect類,傳入getter,實(shí)現(xiàn)對(duì)計(jì)算屬性函數(shù)傳入的屬性的數(shù)據(jù)綁定,傳入第二個(gè)參數(shù),在數(shù)據(jù)更新完之后將_dirty標(biāo)記為true,并實(shí)現(xiàn)數(shù)據(jù)更新(triggerEffects)
私有變量_dirty控制數(shù)據(jù)是否更新
其有兩個(gè)方法get value 和 set value
當(dāng)調(diào)用get,讓ReactiveEffect實(shí)例運(yùn)行,獲取其返回值賦值給內(nèi)部變量_value,并返回改變量,將_dirty設(shè)置為false,表示沒(méi)有新的數(shù)據(jù)改變了,可以使用緩存,判斷當(dāng)前環(huán)境是否存在activeEffect,存在則進(jìn)行依賴收集(調(diào)用trackEffects)
調(diào)用set則運(yùn)行setter
完整代碼如下:
import { isFunction } from "@vue/shared" import { activeEffect, trackEffects, triggerEffects,ReactiveEffect } from "./effect"; export function computed(getterOrOptions){ let getter = null; let setter = null; let fn = ()=>{ throw new Error("this function is onlyRead"); } let isGetter = isFunction(getterOrOptions) if(isGetter){ getter = getterOrOptions setter = fn } else { getter = getterOrOptions.get setter = getterOrOptions.set || fn } return new computedRefImpl(getter,setter) } class computedRefImpl{ private _value = null private _dirty = true public effect = null public deps = null constructor(getter,public setter){ this.effect = new ReactiveEffect(getter,()=>{ if(!this._dirty){ this._dirty = true triggerEffects(this.deps) } }) } get value(){ debugger if(activeEffect){ // 存在effect,則進(jìn)行依賴收集 trackEffects(this.deps || (this.deps = new Set()) ) } if(this._dirty){ this._dirty = false this._value = this.effect.run() } return this._value } set value(newValue){ this.setter(newValue) } }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Vue中的methods、computed計(jì)算屬性和watch監(jiān)聽(tīng)屬性的使用和區(qū)別解析
- Vue中computed(計(jì)算屬性)和watch(監(jiān)聽(tīng)屬性)的用法及區(qū)別說(shuō)明
- 為vue中的data賦值computed計(jì)算屬性后,出現(xiàn)undefined原因及解決
- vue計(jì)算屬性computed方法內(nèi)傳參方式
- vue正確使用watch監(jiān)聽(tīng)屬性變化方式
- Vue中的?watch監(jiān)聽(tīng)屬性詳情
- Vue3計(jì)算屬性computed和監(jiān)聽(tīng)屬性watch區(qū)別解析
相關(guān)文章
Vue ECharts簡(jiǎn)易實(shí)現(xiàn)雷達(dá)圖
這篇文章主要介紹了基于Vue ECharts簡(jiǎn)易實(shí)現(xiàn)雷達(dá)圖,本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12VUE2 前端實(shí)現(xiàn) 靜態(tài)二級(jí)省市聯(lián)動(dòng)選擇select的示例
下面小編就為大家分享一篇VUE2 前端實(shí)現(xiàn) 靜態(tài)二級(jí)省市聯(lián)動(dòng)選擇select的示例。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02Vue?element實(shí)現(xiàn)權(quán)限管理業(yè)務(wù)流程詳解
目前本人再使用vue-element-admin項(xiàng)目時(shí)都是通過(guò)直接刪除一些用不上的路由來(lái)進(jìn)行側(cè)邊欄的清除,但是其實(shí)有一個(gè)更加好的辦法來(lái)對(duì)項(xiàng)目的側(cè)邊欄顯示的內(nèi)用進(jìn)行管理,就是權(quán)限管理,其實(shí)也不知道這個(gè)方法好不好,原理上來(lái)說(shuō)時(shí)跟直接刪除該路由的方式時(shí)一樣的2022-08-08Vue+Openlayers實(shí)現(xiàn)實(shí)時(shí)坐標(biāo)點(diǎn)展示
這篇文章主要為大家詳細(xì)介紹了Vue+Openlayers實(shí)現(xiàn)實(shí)時(shí)坐標(biāo)點(diǎn)展示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Vuejs對(duì)象常用操作之取對(duì)應(yīng)的值、取key和value值、轉(zhuǎn)數(shù)組及合并等
最近在學(xué)Vue和javascript感覺(jué)js的好多方法都不太清楚,這里徹底總結(jié)下,這篇文章主要給大家介紹了關(guān)于Vuejs對(duì)象常用操作之取對(duì)應(yīng)的值、取key和value值、轉(zhuǎn)數(shù)組及合并等的相關(guān)資料,需要的朋友可以參考下2024-01-01vue3實(shí)現(xiàn)鼠標(biāo)右鍵顯示菜單,點(diǎn)擊其他地方消失問(wèn)題
這篇文章主要介紹了vue3實(shí)現(xiàn)鼠標(biāo)右鍵顯示菜單,點(diǎn)擊其他地方消失問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04element表單驗(yàn)證如何清除校驗(yàn)提示語(yǔ)
本文主要介紹了element表單驗(yàn)證如何清除校驗(yàn)提示語(yǔ),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10uniapp實(shí)現(xiàn)省市區(qū)三級(jí)級(jí)聯(lián)選擇功能(含地區(qū)json文件)
這篇文章主要給大家介紹了關(guān)于uniapp實(shí)現(xiàn)省市區(qū)三級(jí)級(jí)聯(lián)選擇功能(含地區(qū)json文件)的相關(guān)資料,級(jí)級(jí)聯(lián)是一種常見(jiàn)的網(wǎng)頁(yè)交互設(shè)計(jì),用于省市區(qū)選擇,它的目的是方便用戶在一系列選項(xiàng)中進(jìn)行選擇,并且確保所選選項(xiàng)的正確性和完整性,需要的朋友可以參考下2024-06-06