vue3 watch & watchEffect

The watch & watchEffect functions are both listeners, used to monitor data changes; watch is inert, watchEffect is not inert; watch needs to specify specific monitoring properties, watchEffect does not need to specify specific monitoring properties and configuration parameters, and will automatically sense code dependencies; watch can get the previous old value and new value, watchEffect can only get the latest value

1. watch monitoring

1. watch monitors a single responsive data defined by ref

<script setup>
import { watch, computed } from 'vue'
const num = ref(11)

watch(
 // 监视的数据:监视 ref 所定义的单个响应式数据
 num,
 // 监视回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 // 监视配置:immediate 的默认值是 false,当值为 true 表示立即执行; deep 表示是否深度监听,这里的 deep 无意义
 { immediate: true, deep: true }
)
<script>

2. watch monitors computed properties

<script setup>
import { watch, computed } from 'vue'
const start = ref(1)
const end = computed(() => start.value + 1)

watch(
 // 监视的数据:监视 computed 计算属性
 end,
 // 监视回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 // 监视配置:immediate 的默认值是 false,当值为 true 表示立即执行; deep 表示是否深度监听,这里的 deep 无意义
 { immediate: true, deep: true }
)
<script>

3. watch monitors the getter function

<script setup>
import { watch, computed } from 'vue'
const messages = ref('this is a mesage')

watch(
 // 监视的数据:监视 getter 函数
 () => '返回的消息' + messages.value,
 // 监视回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 // 监视配置:immediate 的默认值是 false,当值为 true 表示立即执行; deep 表示是否深度监听,这里的 deep 无意义
 { immediate: true, deep: true }
)
<script>

4. watch monitors arrays composed of ref, computed, getter functions, etc. of any type

<script setup>
import { watch, computed } from 'vue'
const msg = ref('this is a msg')
const n = ref(1)
const count = computed(() => n.value + 1)

watch(
 // 监视的数据:监视由 ref、computed、getter函数 等任意类型组成的数组
 [msg, n, count, () => n.value + count.value],
 // 监视的回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 // 监视配置:immediate 的默认值是 false,当值为 true 表示立即执行; deep 表示是否深度监听,这里的 deep 无意义
 { immediate: true, deep: true }
)
<script>

5. Watch monitors the responsive object defined by reactive. Deep monitoring is forced to be turned on by default. Even if the monitoring setting is deep:false, it is invalid; it is difficult to obtain the oldValue correctly in the callback. The newVal and oldVal of the callback are the same.

<script setup>
import { watch, reactive } from 'vue'
const obj = reactive({
  name: 'bob',
  age: 18
})

watch(
 // 监视的数据:监视 reactive 所定义的响应式对象
 obj,
 // 监视的回调函数: newVal 和 oldVal 是相同的
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 // 监视配置:immediate 的默认值是 false,当值为 true 表示立即执行; deep 表示是否深度监听,这里的 deep 强制开启,即使手动设置 false 也无效
 { immediate: true, deep: false }
)
<script>

6. watch monitors a certain attribute of the responsive object defined by reactive

<script setup>
import { watch, reactive } from 'vue'
const obj = reactive({
  name: 'bob',
  age: 18,
  sex: '男',
  score: 90,
  info: {
    meta: 'meta'
 }
})

watch(
 // 监视的数据:监视 reactive 所定义的响应式对象属性 name, 注意这里要用 getter 函数的形式书写,如果直接写 obj.name 则无效
 () => obj.name,
 // 监视的回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 }
)

watch(
 // 监视的数据:监视 reactive 所定义的响应式对象属性 age, 注意这里要用 getter 函数的形式书写,如果直接写 obj.age 则无效 
 () => obj.age,
 // 监视的回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 }
)

watch(
 // 监视的数据:监视 reactive 所定义的响应式对象多个属性
 [() => obj.sex, () => obj.score],
 // 监视的回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 }
)

watch(
 // 监视的数据:监视 reactive 所定义的响应式对象属性 info, 注意这里要用 getter 函数的形式书写,如果直接写 obj.info 则无效 
 () => obj.info,
 // 监视的回调函数
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 // 监视配置:immediate 的默认值是 false,当值为 true 表示立即执行; deep 表示是否深度监听,这里的 deep 需要开启,因为 obj.info 是一个对象,如果不开启无法深度监听
 { immediate: true, deep: true }
)
<script>

7. Watch stops monitoring & restarts monitoring

<script setup lang="ts">
import { watch, reactive } from 'vue'
const visible = ref<boolean>(false)

let stopWatch = watch(
 visible,
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 { immediate: true, deep: true }
)
// 停止监听: 将 watch 赋值给一个变量,当达到条件时就调用这个变量来停止监听
setTimeout(() => {
 stopWatch()
}, 3000)

// 重启监听: 将监听器重新赋值给变量
stopWatch = watch(
 visible,
 (newVal, oldVal) => {
  console.log(newVal, oldVal)
 },
 { immediate: true, deep: true }
)
<script>

2. watchEffect monitoring

<script setup>
import { watchEffect, computed, ref,reactive } from 'vue'
const obj = reactive({ name: 'bob',  age: 18 })
const n = ref(1)
const msg = () => n.value + 1
const count = computed(() => n.value + 1)

// 只要 watchEffect 中涉及到数据发生变化,就会执行此回调
watchEffect(() => {
 const objName = obj.name.value
 const nValue = n.value
 const msgValue = msg.value
 const countValue =  count.value
})


// 取消监听
const stop = watchEffect(() => {
 const objName = obj.name.value
 const nValue = n.value

 setTimeout(() => {
  stop()
 }, 5000)
})

// 重启监听
const stop = watchEffect(() => {
 const objName = obj.name.value
 const nValue = n.value
})
<script>

Compared

Compared Is there inertia parameter get value
watch There is laziness, and the listening function is executed after the value changes again. Can listen for changes in multiple data versions Parameters can get the current value and the original
watchEffect Immediate execution without laziness No need to pass listening content, automatically detect code dependencies There is no need to pass in many parameters and the original value cannot be obtained

Guess you like

Origin blog.csdn.net/qq_37600506/article/details/132743085