四 分分钟学会 在vue3中 如何使用 监听器 watch

87 阅读3分钟

1. watch 的优点

可以实时监听响应式数据的变化,可以获取到 newval和oldval 进行自定义的代码逻辑处理

2. watch 三种常用的使用方式

(1)监听单个数据

监听引用数据类型的时候,需要开启deep: true 深度监听

<template>
  <div class="about">
    <!-- 使用响应式数据 -->
    <div>我是data1:{{ data1 }}</div>
    <div>我是data2:{{ data2 }}</div>

    <div>我是data3:{{ data3 }}</div>
    <div>我是data4:{{ data4 }}</div>
    <!-- 修改响应式数据 -->
    <button @click="changeData1">修改data1</button>
    <button @click="changeData3">修改data3</button>
    
  </div>
</template>

<script setup lang="ts">
// 引入watch
import { watch, ref } from 'vue'

// 使用ref声明响应式数据
let data1 = ref({ a: 1, b: { c: 2 } })

let data2 = ref(0)

let data3 = ref(1)

let data4 = ref(0)

// 使用监听器 watch ,监听data1 的变化,并且 将 data1 的值 赋值给 data2
// deep: true 监听引用数据类型的时候,需要开启deep: true,深度监听
watch(data1, (newValue, oldVal) => {
  data2.value = newValue.b.c
}, {
  deep: true
})

const changeData1 = () => {
  data1.value.b.c++
}

// 使用监听器 watch ,监听data1 的变化,并且 将 data3 的值 赋值给 data4
// 监听基本数据类型
watch(data3, (newValue, oldVal) => {
  data4.value = newValue
})

const changeData3 = () => {
  data3.value++
}
</script>

屏幕录制2024-09-17-20.41.32.gif
(2)监听对象中的某个属性
<template>
  <div class="about">
    <!-- 使用响应式数据 -->
    <div>我是data1:{{ data1 }}</div>
    <div>我是data2:{{ data2 }}</div>

    <!-- 修改响应式数据 -->
    <button @click="changeData1">修改data1</button>
    
  </div>
</template>

<script setup lang="ts">
// 引入watch
import { watch, ref } from 'vue'

// 使用ref声明响应式数据
let data1 = ref({ a: 1, b: { c: 2 } })

let data2 = ref(0)


// 使用监听器 watch ,监听data1.b.c 的变化,并且 将 data1.b.c 的值 赋值给 data2
// deep: true 监听引用数据类型的时候,需要开启deep: true,深度监听
watch(() => data1.value.b.c, (newValue, oldVal) => {
  data2.value = newValue
}, {
  deep: true
})

const changeData1 = () => {
  data1.value.b.c++
}

</script>

屏幕录制2024-09-17-20.47.24.gif
(3)监听多个数据
<template>
  <div class="about">
    <!-- 使用响应式数据 -->
    <div>我是data1:{{ data1 }}</div>
    <div>我是data2:{{ data2 }}</div>
    <div>我是data4:{{ data5 }}</div>


    <div>我是data3:{{ data3 }}</div>
    <div>我是data4:{{ data4 }}</div>

    <!-- 修改响应式数据 -->
    <button @click="changeData1">修改data1.b.c</button>
    <button @click="changeData2">修改data3</button>
    
  </div>
</template>

<script setup lang="ts">
// 引入watch
import { watch, ref } from 'vue'

// 使用ref声明响应式数据
let data1 = ref({ a: 1, b: { c: 2 } })

let data2 = ref(0)

let data3 = ref(1)

let data4 = ref(0)

let data5 = ref(0)

// 使用监听器 watch ,同时监听data1.b.c  data1  data3 的变化
// deep: true 监听引用数据类型的时候,需要开启deep: true,深度监听
watch([() => data1.value.b.c, data1, data3], (newValue, oldVal) => {
  data2.value = newValue[0];  // data1.value.b.c 更新后的值
  data5.value = newValue[1].b.c; // data1 更新后的值
  data4.value = newValue[2]   // data3 更新后的值
}, {
  deep: true
})

// 修改 data1.value.b.c data2 和 data5 数据发生变化
const changeData1 = () => {
  data1.value.b.c++
}

// 修改 data3,  data4 数据发生变化
const changeData2 = () => {
  data3.value++
}

</script>

屏幕录制2024-09-17-20.58.27.gif

注意: immediate 属性

watch 内部的逻辑代码。页面初始化渲染后不加载,后面在数据更新时会加载,

设置 immediate: true ,页面初始化后,默认就是执行一次,watch内部的代码逻辑

// 使用监听器 watch ,同时监听data1.b.c  data1  data3 的变化
// deep: true 监听引用数据类型的时候,需要开启deep: true,深度监听
// immediate: true 时 页面加载后默认就会 执行一次 watch里面的逻辑
watch([() => data1.value.b.c, data1, data3], (newValue, oldVal) => {
  data2.value = newValue[0];  // data1.value.b.c 更新后的值
  data5.value = newValue[1].b.c; // data1 更新后的值
  data4.value = newValue[2]   // data3 更新后的值
}, {
  deep: true,
  immediate: true
})