xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

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, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2022-04-02 14:43  xgqfrms  阅读(1170)  评论(7编辑  收藏  举报