Vue 3.0 響應(yīng)性API Computed與watch

2021-07-16 11:27 更新

本節(jié)例子中代碼使用的單文件組件語(yǔ)法

#computed

使用 getter 函數(shù),并為從 getter 返回的值返回一個(gè)不變的響應(yīng)式 ref 對(duì)象。

  1. const count = ref(1)
  2. const plusOne = computed(() => count.value + 1)
  3. console.log(plusOne.value) // 2
  4. plusOne.value++ // error

或者,它可以使用具有 getset 函數(shù)的對(duì)象來(lái)創(chuàng)建可寫(xiě)的 ref 對(duì)象。

  1. const count = ref(1)
  2. const plusOne = computed({
  3. get: () => count.value + 1,
  4. set: val => {
  5. count.value = val - 1
  6. }
  7. })
  8. plusOne.value = 1
  9. console.log(count.value) // 0

類(lèi)型聲明:

  1. // read-only
  2. function computed<T>(getter: () => T): Readonly<Ref<Readonly<T>>>
  3. // writable
  4. function computed<T>(options: { get: () => T; set: (value: T) => void }): Ref<T>

#watchEffect

在響應(yīng)式地跟蹤其依賴(lài)項(xiàng)時(shí)立即運(yùn)行一個(gè)函數(shù),并在更改依賴(lài)項(xiàng)時(shí)重新運(yùn)行它。

  1. const count = ref(0)
  2. watchEffect(() => console.log(count.value))
  3. // -> logs 0
  4. setTimeout(() => {
  5. count.value++
  6. // -> logs 1
  7. }, 100)

類(lèi)型聲明:

  1. function watchEffect(
  2. effect: (onInvalidate: InvalidateCbRegistrator) => void,
  3. options?: WatchEffectOptions
  4. ): StopHandle
  5. interface WatchEffectOptions {
  6. flush?: 'pre' | 'post' | 'sync' // default: 'pre'
  7. onTrack?: (event: DebuggerEvent) => void
  8. onTrigger?: (event: DebuggerEvent) => void
  9. }
  10. interface DebuggerEvent {
  11. effect: ReactiveEffect
  12. target: any
  13. type: OperationTypes
  14. key: string | symbol | undefined
  15. }
  16. type InvalidateCbRegistrator = (invalidate: () => void) => void
  17. type StopHandle = () => void

參考watchEffect 指南

#watch

watch API 與選項(xiàng)式 API this.$watch (以及相應(yīng)的 watch 選項(xiàng)) 完全等效。watch 需要偵聽(tīng)特定的 data 源,并在單獨(dú)的回調(diào)函數(shù)中副作用。默認(rèn)情況下,它也是惰性的——即,回調(diào)是僅在偵聽(tīng)源發(fā)生更改時(shí)調(diào)用。

  • 與 watchEffect 比較,watch 允許我們:
    • 惰性地執(zhí)行副作用;
    • 更具體地說(shuō)明應(yīng)觸發(fā)偵聽(tīng)器重新運(yùn)行的狀態(tài);
    • 訪問(wèn)偵聽(tīng)狀態(tài)的先前值和當(dāng)前值。

#偵聽(tīng)一個(gè)單一源

偵聽(tīng)器 data 源可以是返回值的 getter 函數(shù),也可以是 ref

  1. // 偵聽(tīng)一個(gè)getter
  2. const state = reactive({ count: 0 })
  3. watch(
  4. () => state.count,
  5. (count, prevCount) => {
  6. /* ... */
  7. }
  8. )
  9. // 直接偵聽(tīng)一個(gè)ref
  10. const count = ref(0)
  11. watch(count, (count, prevCount) => {
  12. /* ... */
  13. })

#偵聽(tīng)多個(gè)源

偵聽(tīng)器還可以使用數(shù)組同時(shí)偵聽(tīng)多個(gè)源:

  1. watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
  2. /* ... */
  3. })

#watchEffect 共享行為

watchwatchEffect手動(dòng)停止副作用無(wú)效 (將 onInvalidate 作為第三個(gè)參數(shù)傳遞給回調(diào)),flush timingdebugging 有共享行為。

類(lèi)型聲明:

  1. // 偵聽(tīng)單一源
  2. function watch<T>(
  3. source: WatcherSource<T>,
  4. callback: (
  5. value: T,
  6. oldValue: T,
  7. onInvalidate: InvalidateCbRegistrator
  8. ) => void,
  9. options?: WatchOptions
  10. ): StopHandle
  11. // 偵聽(tīng)多個(gè)源
  12. function watch<T extends WatcherSource<unknown>[]>(
  13. sources: T
  14. callback: (
  15. values: MapSources<T>,
  16. oldValues: MapSources<T>,
  17. onInvalidate: InvalidateCbRegistrator
  18. ) => void,
  19. options? : WatchOptions
  20. ): StopHandle
  21. type WatcherSource<T> = Ref<T> | (() => T)
  22. type MapSources<T> = {
  23. [K in keyof T]: T[K] extends WatcherSource<infer V> ? V : never
  24. }
  25. // 參見(jiàn) `watchEffect` 類(lèi)型聲明共享選項(xiàng)
  26. interface WatchOptions extends WatchEffectOptions {
  27. immediate?: boolean // default: false
  28. deep?: boolean
  29. }

參考watch 指南

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)