美文网首页
2022-10-21 vue3 watch watchEffec

2022-10-21 vue3 watch watchEffec

作者: 忙于未来的民工 | 来源:发表于2022-10-21 17:53 被阅读0次

    vue3中watch的用法,比2复杂很多。

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

    watch函数接受三个参数,
    第一个监听的数据源:可以是一个函数返回一个值、ref、reactive、或者由以上三种组成一个数组(监听多个数据源)
    第二个数据源变动时执行的回调函数,执行时机默认是渲染之前
    第三个类似于2的参数,immediate、deep、flush(回调执行时机)

    1:监听基本数据类型和一个函数,直接使用即可。

      const a = reactive({b: 1})
      watch(
        () => a.b,
        (value, oldValue) => {
          console.log(value, oldValue)
        }
      )
    

    2:监听多个数据源

      const a = ref('aaa')
      const b = ref('bbbb')
    
      watch([a, b], ([a, b], [preva, prevb]) => {
      })
    

    注意:如果a和b在渲染之前都被改变,只执行一次,若一个在渲染前一个在渲染后,则回调执行两次

    3:监听引用数据源,数据源定义分为ref和reactive
    ref定义,数组中为基本数据类型,只能获取当前值,
    如果数组中是引用数据类型,需要加deep才能获取当前值:

    const arrayRef = ref([1, 2, 3, 4])
    watch(
     arrayRef,
     (newValue, oldValue) => {
       console.log('new', newValue, 'old', oldValue)
     },
    )
    

    ref定义,获取老值和新值,
    如果数组中是引用数据类型,需要加deep才能获取当前值和老值:

    const arrayRef = ref([1, 2, 3, 4])
    watch(
      () => [...arrayRef.value],
      (newValue, oldValue) => {
       console.log('new', newValue, 'old', oldValue)
      },
    )
    

    reactive 定义,只能获取新值
    如果数组中是引用数据类型,不需要加deep,reactive默认添加:

    const arrayRef = reactive([1, 2, 3, 4])
    watch(arrayRef, (newValue, oldValue) => {
      console.log('new', newValue, 'old', oldValue)
    })
    

    reactive 定义,可以获取新值和老值,
    如果数组中是引用数据类型,需要加deep才能获取当前值:

    const arrayRef = reactive([1, 2, 3, 4])
    watch(
      () => [...arrayRef],
      (newValue, oldValue) => {
        console.log('new', newValue, 'old', oldValue)
      }
    )
    

    总结:如果直接监听数据源,无法获取老值,如果监听get函数,可以获取老值,如果数组中是引用数据类型,ref定义需要添加deep,reactive定义直接监听不需要加,监听get函数需要加。

    watchEffect:

    function watchEffect(
      effect: (onCleanup: OnCleanup) => void,
      options?: WatchEffectOptions
    ): StopHandle
    
    type OnCleanup = (cleanupFn: () => void) => void
    
    interface WatchEffectOptions {
      flush?: 'pre' | 'post' | 'sync' // 默认:'pre'
      onTrack?: (event: DebuggerEvent) => void
      onTrigger?: (event: DebuggerEvent) => void
    }
    
    type StopHandle = () => void
    
    

    接受两个参数,
    第一个是回调函数,在代码初始化时会立即执行,并且会同时收集依赖。回调函数有一个参数(OnCleanup),主要作用是在当该回调函数在执行任务时(还未执行完,比如在函数中包含异步函数),再次触发了该回调,这个时候在执行该回调之前会执行一次OnCleanup钩子。OnCleanup的执行时机可以简单理解为当该回调执行一次后,在该回调下次执行之前执行。
    第二个是options参数。
    例子:

    
    const a = reactive({ b: 1 })
    watchEffect(OnCleanup => {
      console.log(a.b) // 收集依赖
      let timer = setTimeout(() => {
        console.log(2222) // 理论上应该执行两次,但是因为OnCleanup 所以 执行一次
      }, 8000)
      OnCleanup(() => {
        console.log('执行OnCleanup')
        clearTimeout(timer)
      })
    })
    setTimeout(() => {
      a.b = 3
    }, 5000)
    

    相关文章

      网友评论

          本文标题:2022-10-21 vue3 watch watchEffec

          本文链接:https://www.haomeiwen.com/subject/wwlmzrtx.html