vue3 新特性 computed、watch、watchEffect 看完就會
1、watchEffect
watchEffect 偵聽器是一個副作用函式,不需要指定監聽的某個屬性,監視的回撥中用到哪個屬性,就會監聽哪個屬性,一旦執行就會立即執行。
watchEffect 與 computed 類似,computed 注重計算出來的結果,所以必須要返回值,而它注重的是過程,所以不用寫返回值。
使用語法:
watchEffect(() => { //需要監聽的屬性}, WatchEffectOptions)// WatchEffectOptions 更多的配置項
watchEffect 使用例項:
型別
重新整理頁面,首次進入的時候,watchEffect 回撥函式會自動執行。
為什麼說 watchEffect 是副作用函式呢?
副作用函式就是指會產生副作用的函式,也就是說函式在執行的時候會直接或間接影響其他函式的執行。watchEffect 副作用就是 DOM 掛載或更新之前就會觸發。
執行下面的例項,發現:
第一次獲取到的元素是 null,執行第二次監聽的時候才會獲取到元素。
如何清除 watchEffect 的副作用呢?
上述的問題可以透過 flush:post 可以避免副作用,在 DOM 更新後執行副作用,確保模板引用與 DOM 保持同步,並引入正確元素。
WatchEffectOptions 主要作用是指定排程器,何時執行副作用函式。它是一個可選引數,具體屬性值有:
flush
onTrack
onTrigger
flush 定義元件重新整理時機,它有三個值,分別表示意義如下:
pre
sync
post
更新時機
元件
更新前
執行
強制效果始終同步觸發
元件
更新後
執行
onTrack 和 onTrigger 用於除錯一個偵聽器的行為。
清除副作用函式(onInvalidate)
watchEffect 的第一個引數回撥函式,也有自己的引數 —— onInvalidate。它也是一個函式,用於清除 effect 產生的副作用。
watchEffect
oninvalidate 只作用於非同步函式,只有兩種情況才會被呼叫:
watchEffect 第一個引數 effect 回撥函式,當 effect 被重新呼叫時。
當監聽器被登出時。
如何停止監聽?
副作用是伴隨元件載入而發生的,在元件解除安裝時,就需要清理這些副作用。watchEffect 的返回值依舊是一個函式,呼叫它的返回函式時就會清除監聽,經常在元件被解除安裝時呼叫。
setup() { const stop = watchEffect(() => { /* 。。。 */ }); // 呼叫之後,清除監聽 stop();}
2、watch
監聽某個特定屬性,並能夠返回改變前後的值。使用語法:
watch( name,//需要監聽的源 (newVal, oldVal) => {}, //返回改變前後的值 options //可選配置項)
在頁面剛進入的時候並不會立即執行,只有監聽的源資料改變時才會執行。可以監聽的源資料可以是一個也可以是多個。
示例如下:
如果 watch 監聽一個 ref 定義深層資料,修改值的時候會被監聽到嗎?
let nav: any = ref({ bar: { name: ‘menu’, },})watch( nav, (newV, oldV) => { console。log(‘newV’, newV) })
當我們修改 nav。bar。name 的屬性值的時候,發現監聽內的回撥函式並沒有執行。此時如何解決該問題呢?
watch 函式還有一個 可選的 options 引數,它的配置項有:
deep 表示是否深度監聽,是 boolean 值 ,預設是 false 。
immediate 是否立即執行。
解決 watch 無法深層監聽 ref 方法1:新增 deep 配置項
let nav: any = ref({ bar: { name: ‘menu’, },})watch(nav, (newV, oldV) => { console。log(‘newV’, newV) }, { deep:true })
解決 watch 無法深層監聽 ref 方法2:ref 替換成 reactive
let nav: any = reactive({ bar: { name: ‘11’, }, menu: { name: ‘22’, },})watch(nav, (newV, oldV) => { console。log(‘newV’, newV。bar。name) console。log(‘newV’, newV。menu。name)})
使用 reactive 監聽深層物件開啟和不開啟 deep 效果是一樣的。修改 nav。bar。name 或 nav。menu。name 的時候,都會觸發函式。如果我們只是想監聽其中一個屬性該如何處理呢?
監聽 reactive 單一值
let nav: any = reactive({ bar: { name: ‘1’, }, menu: { name: ‘2’, },})watch( () => nav。bar。name, (newV, oldV) => { console。log(‘newV’, newV) },)
3、computed
計算屬性就是當依賴的屬性值發生改變的時候,才會觸發它的更改,如果依賴的值不發生改變,使用的是快取中的值。
函式形式使用語法:
import { computed, ref } from “vue”let num: number = ref(0)const res: number = computed((): number => { return num。value * 10})
物件形式使用語法:
import { computed, ref } from “vue”let num: number = ref(0)const res: number = computed({ get: (): number => { return num。value * 10 }, set: (val: number): number => { num。value = val / 10 },})
使用 computed 實現購物車價格計算功能,程式碼:
{{ shopList }} 序號 商品名稱 單價 數量 操作 {{ index + 1 }} {{ item。name }} {{ item。price }} {{ item。num }} 總價:{{ totalPrice }}