Vue3中WatchEffect监听、watch监听、computed计算属性

1,387 阅读2分钟

computed计算属性

只有当computed内的依赖变更时,才重新计算结果(计算属性重点在结果)

watch监听重点在过程

<template>
  <div>num1为:{{ num1 }}</div>
  <br>
  <button @click="num1++">num1++</button>
  <br>
  <div>num2为:{{ num2 }}</div>
  <br>
  <button @click="num2++">num2++</button>
  <br>
  <div>{{ sum }} ={{ num1 }} + {{ num2 }}</div>
</template>

<script setup lang="ts">
import { ref,computed } from "vue";
const num1 = ref(1)
const num2 = ref(1)
const sum = computed(() => num1.value + num2.value)
</script>

结果:

image.png

watch监听

vue3 watch 的作用和 Vue2 中的 watch 作用是一样的,他们都是用来监听响应式状态发生变化的,当响应式状态发生变化时,就会触发一个回调函数。

watch(data,()=>{},{})

  • 参数一,监听的数据
  • 参数二,数据改变时触发的回调函数(newVal更改前的值,oldVal更改后的值)
  • 参数三,options配置项,为一个对象

1、监听ref定义的一个响应式数据

<template>
  <div>{{ msg }}</div>
</template>

<script setup lang="ts">
import { ref,watch } from "vue";
const msg = ref(0)
setInterval(() => { msg.value++ }, 3000)
watch(msg, (newVal, oldVal) => {
  console.log(newVal,oldVal)
})
</script>

监听结果:

image.png

2、监听ref定义的多个响应式数据

监听多个ref定义的数据时,将watch()第一个参数变成数组,多个数据作为数组元素

<template>
  <div>{{ msg1 }}</div>
  <br>
  <div>{{ msg2 }}</div>
</template>

<script setup lang="ts">
import { ref,watch } from "vue";
const msg1 = ref(100)
const msg2 = ref(200)
setInterval(() => { msg1.value++, msg2.value++}, 3000)
watch([msg1,msg2], (newVal, oldVal) => {
  console.log(newVal,oldVal)
})
</script>

监听结果:

image.png

3、监听Reactive定义的响应式对象

当 watch 监听的是一个响应式对象时,会隐式地创建一个深层侦听器,即该响应式对象里面的任何属性发生变化,都会触发监听函数中的回调函数。

注意:

  1. 即当 watch 监听的是一个响应式对象时,默认开启 deep:true
  2. 监听不到,更改前的数据
<template>
  <div>{{ msg1.name }}</div>
  <br>
  <div>{{ msg1.age }}</div>
</template>

<script setup lang="ts">
import { reactive,watch } from "vue";
const msg1 = reactive({
  name: '张三',
  age:18
})
setInterval(() => { msg1.name = '李四',msg1.age++ }, 3000)
watch(msg1, (newVal, oldVal) => {
  console.log(newVal,oldVal)
}, {immediate:true})
</script>

监听结果:

image.png

4、监听reactive 定义响应式对象的单一属性

如果要监听响应式对象中的某个属性,我们可以使用 getter 函数的形式,即将watch第一个参数修改成一个回调函数的形式

将watch第一个参数,写成回调参数的形式

<template>
  <div>{{ msg1.name }}</div>
  <br>
  <div>{{ msg1.age }}</div>
</template>

<script setup lang="ts">
import { reactive,watch } from "vue";
const msg1 = reactive({
  name: '张三',
  age:18
})
setInterval(() => { msg1.name = '李四',msg1.age++ }, 3000)

watch(()=> msg1.age, (newVal, oldVal) => {
  console.log(newVal,oldVal)
}, {immediate:true})
</script>

监听结果:

image.png

5.监听reactive定义的 引用数据(监听深层的对象)

注意:

  1. watch 监听的是一个响应式对象的深层对象时,要加deep:true
  2. 监听不到,更改前的数据
<template>
  <div>{{ msg1.num.num1 }}</div>
  <br>
  <div>{{ msg1.num.num2 }}</div>
</template>

<script setup lang="ts">
import { reactive,watch } from "vue";
const msg1 = reactive({
  name: '张三',
  age: 18,
  num: {
    num1: 100,
    num2: 200
  }
})
setInterval(() => { msg1.num.num1++, msg1.num.num2++}, 3000)
watch(()=> msg1.num, (newVal, oldVal) => {
  console.log(newVal,oldVal)
}, {immediate:true,deep:true})
</script>

监听结果:

image.png

WatchEffect监听(推荐)

watchEffect 不需要指定要监听的数据,而是会自动追踪函数中使用的响应式数据,并在这些数据发生变化时重新执行回调函数

watchEffect 只有一个回调函数,自动追踪函数中用到的数据,任何一个数据,变动一次就执行回调函数

<template>
  <div>{{ msg1.num.num1 }}</div>
</template>

<script setup lang="ts">
import { reactive,watchEffect } from "vue";
const msg1 = reactive({
  name: '张三',
  age: 18,
  num: {
    num1: 1,
  }
})
setInterval(() => { msg1.num.num1++}, 3000)
watchEffect(() => {
  console.log('监听深层对象',msg1.num.num1)
})
</script>