VUE2进阶至VUE3 三(watch&watchEffect)

3,025 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

本文接着介绍并学习vue3,因为有vue2的基础所以这里不做对于computed的介绍,相信有跟我一样的宝子们,只是想单纯且快速的上手了解vue3,那么下面就愉快的开始吧。

watch

  • 介绍:数据发生改变后根据一个回调侦听这个改变
  • 使用:
<template>
  <div>
    <input type="text" v-model="mesg" id="input">
  </div>
</template>
<script setup lang="ts">
  import { watch, ref } from 'vue'
  let mesg = ref<string>('')
  watch(mesg, (newval, oldval) => {
    console.log('new', newval);
    console.log('old',oldval);
  })
  // 此方法与vue2一致,不过多介绍
</script>

特点:与vue2不同的是可以监听多个数据,多个数据用数组类型。 例子:

  import { watch, ref } from 'vue'
  let mesg = ref<string>('')
  let mesg1 = ref<string>('')
  watch([mesg, mesg1], (newval, oldval) => { // 此时的newVal和oldval也是数组
    console.log('new', newval);
    console.log('old',oldval);
  })

当我们需要侦听多层数据:

1、如果使用的是ref定义数据,那么需要传入第三个参数 deep: true 这个配置项意思为是否进行深度监听。

2、如果使用的是reactive监听深层次对象则开启和不开启deep的效果是一样的。

使用reactive监听多个值时,只想监听一个,利用回调函数返回对象中的某个值。如下:

<template>
  <div>
    <input type="text" v-model="mesg.name" id="input">
    <input type="text" v-model="mesg.name1" id="input">
  </div>
</template>
<script setup lang="ts">
  import { watch, reactive } from 'vue'
  let mesg = reactive({
    name: '1',
    name1: '2'
  })
  // reactive触发单一值监听
  watch(() => {mesg.name}, (newval, oldval) => {
    console.log('new', newval);
    console.log('old',oldval);
  })
</script>

注意:此处有一个遗留bug就是深层次监听时旧值显示的也是新值,所以小伙伴们此处有需求的话需要自己单独存一下哦~

需要进入页面立即执行wactch

1、在传入的第三个参数中写入配置项 immediate:true

watchEffect

  • 介绍: 接收的第一个参数一个effect的回调函数,它不需要指定监听属性,会自动收集依赖。所以只要我们在回调中用到了响应式的属性,这个回调就是会执行的,也就说进入页面就会执行这个函数。

    下面介绍一个小例子:

  import { watchEffect, ref } from 'vue'
  let mesg = ref<string>('jxx')
  watchEffect(() => {
    console.log(mesg.value)
  })

onInvalidate

  • 介绍:清除副作用。在接收的effect函数中,还有一个回调函数就是onInvalidate。可以帮助我们最开始来干一些事情,例如节流防抖。
  • 使用:
import { watchEffect, ref } from 'vue'
  let mesg = ref<string>('jxx')
  watchEffect((onInvalidate) => {
    console.log(mesg.value);
    onInvalidate(() => {
        console.log('执行');
    });
    // 输出顺序: 执行,jxx 无论onInvalidate这个回调函数放在哪里都会先执行onInvalidate这个回调函数
  })

停止监听

  • 介绍: watchEffect有一个返回值,可以停止监听
  • 使用:
import { watchEffect, ref } from 'vue'
  let mesg = ref<string>('jxx')
  let stop = watchEffect(() => {
    console.log(mesg.value);
  })
  const handleClick = () => stop(); // 当点击这个handleClick就会停止监听

配置选项

介绍: 也是watchEffect的第二个参数,也就是可以作为一个调试器来使用,希望组件在何时去使用,在我的理解也算是一个小的生命周期。

<template>
  <div>
    <input type="text" v-model="mesg" id="input">
  </div>
</template>
<script setup lang="ts">
  import { watchEffect, ref } from 'vue'
  let mesg = ref<string>('jxx')
  watchEffect(() => {
    let input: HTMLInputElement = document.querySelector('#input') as HTMLInputElement;
    console.log(mesg.value)
    console.log(input, 111)
  }, {
    flush: "post", //此时这个函数会在组件更新之后去执行,其余参数见下表
    onTrigger(e) { //作为一个调试工具,可在开发中方便调试
      debugger;
    },
  })
</script>

flush

类型presyncpost
定义组件更新之前执行强制效果始终同步发生组件更新之后执行

总结

  • watchEffect不用指定监听属性,它会自己收集依赖。只要回调中引用的响应式属性发生了变化这个回调就会执行,而watch必须指定一个或多个属性才能做出变更。
  • watch能够获取到新值与旧值进行比较,但是watchEffect不行。
  • watchEffect会在组件初始化的时候会执行收集依赖,而watch指定了依赖,所以不用。