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

相关推荐

  1. Vue3 watch侦听器

    2024-05-14 15:02:09       44 阅读
  2. vue3watch

    2024-05-14 15:02:09       58 阅读
  3. vue3从精通到入门10:侦听器watch

    2024-05-14 15:02:09       40 阅读
  4. Vue侦听器Watch)深度分析

    2024-05-14 15:02:09       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-14 15:02:09       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-14 15:02:09       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-14 15:02:09       82 阅读
  4. Python语言-面向对象

    2024-05-14 15:02:09       91 阅读

热门阅读

  1. 前端面试题大合集4----框架篇(React)

    2024-05-14 15:02:09       31 阅读
  2. react18+ts如何生成二维码并且下载

    2024-05-14 15:02:09       36 阅读
  3. Kibana初始化启动失败原因及解决办法

    2024-05-14 15:02:09       38 阅读
  4. Day38 斐波那契数 + 爬楼梯 + 使用最小花费爬楼梯

    2024-05-14 15:02:09       32 阅读
  5. 瑞鹤仙——熊市出英雄

    2024-05-14 15:02:09       27 阅读
  6. mysql 拆分字段位多行

    2024-05-14 15:02:09       23 阅读
  7. Docker alpine linux 修改时区

    2024-05-14 15:02:09       36 阅读