Vue 3 watch & watchEffect & watchPostEffect & watchSyncEffec All In One


Vue 3 watch & watchEffect & watchPostEffect & watchSyncEffec All In One

Composition API

Reactivity: Core

ref()
computed()
reactive()
readonly()
watchEffect()
watchPostEffect()
watchSyncEffect()
watch()

watch

// watching single source
function watch<T>(
  source: WatchSource<T>,
  callback: WatchCallback<T>,
  options?: WatchOptions
): StopHandle

// watching multiple sources
function watch<T>(
  sources: WatchSource<T>[],
  callback: WatchCallback<T[]>,
  options?: WatchOptions
): StopHandle

type WatchCallback<T> = (
  value: T,
  oldValue: T,
  onCleanup: (cleanupFn: () => void) => void
) => void

type WatchSource<T> =
  | Ref<T> // ref
  | (() => T) // getter
  | T extends object
  ? T
  : never // reactive object

interface WatchOptions extends WatchEffectOptions {
  immediate?: boolean // default: false
  deep?: boolean // default: false
  flush?: 'pre' | 'post' | 'sync' // default: 'pre'
  onTrack?: (event: DebuggerEvent) => void
  onTrigger?: (event: DebuggerEvent) => void
}



https://vuejs.org/api/reactivity-core.html#watch

https://vuejs.org/guide/essentials/watchers.html

https://vuejs.org/guide/extras/reactivity-in-depth.html#watcher-debugging

watchEffect

function watchEffect(
  effect: (onCleanup: OnCleanup) => void,
  options?: WatchEffectOptions
): StopHandle

type OnCleanup = (cleanupFn: () => void) => void

interface WatchEffectOptions {
  flush?: 'pre' | 'post' | 'sync'
  // default: 'pre'
  onTrack?: (event: DebuggerEvent) => void
  onTrigger?: (event: DebuggerEvent) => void
}

type StopHandle = () => void

watchEffect demos

const count = ref(0);

// 立即執行一次
watchEffect(() => console.log(count.value))
// -> logs 0

// 依賴改變,重新執行
count.value++
// -> logs 1

// 第一個參數是要運行的效果函數
// 效果函數接收可用於注冊清理回調的函數
// 清理回調將在下一次重新運行效果之前調用
// 類似 react hooks cleanup, 在依賴變更后,先執行 clear 
watchEffect(async (onCleanup) => {
  // Promise 異步請求
  const { response, cancel } = doAsyncWork(id.value);
  // `cancel` will be called if `id` changes,so that previous pending request will be cancelled,if not yet completed;
  onCleanup(cancel);
  data.value = await response;
})

// watchEffect 返回值是一個 watch 的停止方法,調用后會清除 watch
const stop = watchEffect(() => {})

// when the watcher is no longer needed,
stop()

// 返回值是一個句柄函數,可以調用它來阻止 effect 再次運行。
// 第二個參數是一個可選的選項對象,可用於調整效果的刷新時間或調試效果的依賴關系。
watchEffect(() => {}, {
  // 等價於  watchPostEffect
  flush: 'post',
  onTrack(e) {
    debugger
  },
  onTrigger(e) {
    debugger
  }
})

// onTrack 和 onTrigger 觀察程序選項僅在開發模式下有效。

watchEffect(callback, {
  onTrack(e) {
    debugger
  },
  onTrigger(e) {
    debugger
  }
})

watch(source, callback, {
  onTrack(e) {
    debugger
  },
  onTrigger(e) {
    debugger
  }
})
// computed
computed(callback, {
  // 當響應式屬性或引用被跟蹤為依賴項時將被調用。
  onTrack(e) {
    debugger
  },
  // 當觀察者回調被依賴的突變觸發時。
  onTrigger(e) {
    debugger
  }
})
// computed
const plusOne = computed(() => count.value + 1, {
  onTrack(e) {
     // 當該屬性被跟蹤為依賴項時候
    // triggered when count.value is tracked as a dependency
    debugger
  },
  onTrigger(e) {
    // 屬性值發生變化時候
    // triggered when count.value is mutated
    debugger
  }
})

// access plusOne, should trigger onTrack
console.log(plusOne.value)

// mutate count.value, should trigger onTrigger
count.value++

https://vuejs.org/api/reactivity-core.html#watcheffect

watchPostEffect



https://vuejs.org/api/reactivity-core.html#watchposteffect

watchSyncEffect



https://vuejs.org/api/reactivity-core.html#watchsynceffect

demo



<template>
  <h1>msg = {{ msg }}</h1>
  <div>
    <input v-model="msg">
  </div>
  <div>
    computedMsg = <span>{{computedMsg}}</span>
  </div>
  <!-- 
    <h1>{{ count }}</h1>
  -->
  <button @click="add">add</button>
  <button @click="minus">minus</button>
</template>

<style>
  div {
    margin: 20px 0;
  }
  button {
    margin-right: 30px;
  }
</style>

<script setup>
import {
  ref,
  computed,
  watch,
  watchEffect,
} from 'vue'

let msg = ref('👻');

const count = ref(0);

/*
const cleanup = () => {
  console.log('clear');
}

const onCleanup = () => {
  console.log('clear');
}
*/

// 立即執行一次
watchEffect(async (cleanup) => {
  cleanup(() => {
    console.log('clear');
  });
  console.log(count.value);
})
// -> logs 0
  
/*

watchEffect(async (onCleanup) => {
  onCleanup(() => {
    console.log('clear');
  });
  console.log(count.value);
})

// 立即執行一次
watchEffect(() => {
  console.log('count.value =', count.value);
})
// -> logs 0

watchEffect(async (cleanup) => {
  cleanup();
  console.log(count.value);
})

watchEffect(async (onCleanup) => {
  onCleanup();
  console.log(count.value);
})

*/
  
const computedMsg = computed(() => {
  return count.value;
});

const add = () => {
  // 依賴改變,重新執行
  count.value++;
  // msg = count.value;
  // -> logs 1
}
const minus = () => {
  // 依賴改變,重新執行
  if(count.value) {
    count.value--;
    // msg = count.value;
  }
}



</script>

zh-Hans

new 💩

https://staging-cn.vuejs.org/api/reactivity-core.html

https://github.com/vuejs-translations/docs-zh-cn

old 👎

https://v3.cn.vuejs.org/api/refs-api.html#ref

https://github.com/vuejs/docs-next-zh-cn

refs

https://vuejs.org/api/reactivity-core.html

https://vuejs.org/guide/extras/composition-api-faq.html



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 發布文章使用:只允許注冊用戶才可以訪問!

原創文章,版權所有©️xgqfrms, 禁止轉載 🈲️,侵權必究⚠️!



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM