vue3 watch与computed

140 阅读2分钟
computed使用

computed使用相较之前的使用没有太多变化,会返回一个ref对象,也支持get,set形式

import {computed} from 'vue'

const count = ref(1)
const plusOne = computed(() => count.value + 1)
count.value++
console.log(plusOne.value)
watch使用

watch的变化多了些,或者功能更强大了

  1. watch和之前的$watch差不多,支持更多的数据监听模式,options多了一个flush
import {watch, ref, reactive} from 'vue'

const str = ref('')
const num = ref(0)
const obj = reactive({
    foo: 1
})
watch([str, num], ([newStr, newNum], [oldStr, oldNum]) => {
    /* ... */
},{
    deep: true,
    immediate: trueflush: 'post'
})
// 函数形
watch(() => obj.foo, (newFoo, oldFoo) => {
    /* ... */
})
  1. watchEffect 这个厉害了。立即执行回调函数,不用指定监听数据,会自动追踪函数内部使用的响应式变量,第二个参数是options对象,支持三个属性。返回一个函数,用来停止侦听。
interface WatchEffectOptions {
  flush?: 'pre' | 'post' | 'sync' // 默认:'pre'
  onTrack?: (event: DebuggerEvent) => void
  onTrigger?: (event: DebuggerEvent) => void
}

flush参数

  • 默认pre
  • post 会将回调在组件更新后触发,这样你就可以访问更新的 DOM,这也导致回调执行会被推迟到组件首次渲染完成。
  • sync 强制效果始终同步触发 onTrackc和onTrigger参数只在开发模式有,方便开发调试
  • onTrack 将在响应式 property 或 ref 作为依赖项被追踪时被调用。
  • onTrigger 将在依赖项变更导致副作用被触发时被调用。

使用示例

import {watchEffect, ref, reactive} from 'vue'

const count = ref(0)
const obj = reactive({
    num: 1,
    str: 'ss'
})
// 返回一个函数,用来停止监听
const stop = watchEffect(() => {
    console.log(count.num)
}, {})
count.num++

// later
stop()

回调函数会注入一个参数onInvalidate是一个参数支持放入一个回调函数,会在回调执行之前执行,用来支持做一些清除工作, watchEffect第一个参数,watch第三个参数。

  • 注:经过测试,首次执行监听回调的时候,onInvalidate里面传入的回调不会执行
import {watchEffect, ref, reactive} from 'vue'

const num = ref(0);
watchEffect((onInvalidate) => {
   console.log('后执行', num.value)
   onInvalidate(() => {
       console.log('先执行')
   })
})
num.value++
    

还有两个方法:

  • watchPostEffect 对标-> flush: 'post'
  • watchSyncEffect 对标-> flush: 'sync'