vue3中的watch侦听器

在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM ,或是根据异步操作的结果去修改另一处的状态。在组合式 API 中,我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数。

 watch 函数可以侦听被 ref reactive 包裹的数据。

 watch 函数包含三个参数:

  1. 参数一: sources 被侦听的数据源;
  2. 参数二: cb callback 回调函数,函数中包含两个参数分别为新值和旧值;
  3. 参数三: options 侦听器的配置项, deep immediate 等参数。

1. watch 的常规写法 

<template>
  <div>姓名:<input type="text" v-model="name" /></div>
</template>

<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
const name = ref<string>('张三')
watch(name, (newVal: any, oldVal: any) => {
  console.log(newVal, oldVal)
})
</script>

当输入框中值发生变化时,侦听器会监听并在控制台打印出来:

2. watch侦听多个数据

 watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref  (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组,侦听多个数据时:

<template>
  <div>姓名:<input type="text" v-model="name" /></div>
  <div>年龄:<input type="number" v-model="age" /></div>
</template>

<script setup lang="ts">
  import { ref, reactive, watch } from 'vue'
  const name = ref<string>('张三')
  const age = ref<number>(20)
  watch([name, age], (newVal: any, oldVal: any) => {
    console.log(newVal, oldVal)
  })
</script>

当被侦听的数据发生改变时:

3. watch侦听对象

(1)侦听使用 ref 的对象时,需要在侦听器的配置项中配置 deep true

<template>
  <div>年龄:<input type="text" v-model="obj.foo.bar.name" /></div>
</template>

<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
const obj = ref({
  foo: {
    bar: {
      name: '张三'
    }
  }
})
watch(
  obj,
  (newVal: any, oldVal: any) => {
    console.log(newVal, oldVal)
  },
  {
    deep: true // 深度监听
  }
)
</script>

由于对象是引用类型,新值和旧值指向同一内存地址,所以值一样。 

(2)侦听使用 reactive 的对象时,不需要设置侦听器的配置项 deep

<template>
  <div>年龄:<input type="text" v-model="obj.foo.bar.name" /></div>
</template>

<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
const obj = reactive({
  foo: {
    bar: {
      name: '张三'
    }
  }
})
watch(obj, (newVal: any, oldVal: any) => {
  console.log(newVal, oldVal)
})
</script>

 与上方 ref 一样,由于对象是引用类型,新值和旧值指向同一内存地址,所以值一样。

注意,不能直接侦听响应式对象的属性值,例如:

const obj = reactive({
  foo: {
    bar: {
      name: '张三'
    }
  }
})
watch(obj.foo.bar.name, (newVal: any, oldVal: any) => {
  console.log(newVal, oldVal)
})

会发生警告:

这是因为 watch source 接受的参数不符合要求,只能接受一个 getter effect  ref reactive 或者元素是这几个类型的数组。官方建议用一个返回该属性的 getter 函数:

const obj = reactive({
  foo: {
    bar: {
      name: '张三'
    }
  }
})

watch(
  () => obj.foo.bar.name,
  (newVal: any, oldVal: any) => {
    console.log(newVal, oldVal)
  }
)

当输入框值改变时:

4.watch的配置项 

  •  deep :布尔值,深度监听,默认 false
  •  immediate :布尔值,在创建侦听器时,立即执行一遍回调,默认 false
  •  plush :字符串,"pre":组件更新之前调用,"sync":同步执行,"post":组件更新之后执行,默认"pre"
  •  once :布尔值,回调只在源变化时触发一次,默认 false
  • 17
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猛扇赵四那半好嘴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值