vue3.0监听属性watch与watchEffect

watch监听

监听reactive定义的数据时
两个小坑:
1.监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)
2.监视reactive定义的响应式数据中某个属性时:deep配置有效

 let sum1 = ref(0);
 let msg = ref("你好啊");
 let person = reactive({
   name: "张三",
   age: 18,
   job: {
     j1: { salary: 20 },
   },
 });
 const data = reactive({
   sum: "",
   name2: "",
 });
 
情况一: 监视ref所定义的响应式数据
 watch(
   sum1,
   (newValue, oldalue) => {
     console.log("sum1变化了",newValue, oldalue);
   },
   { immediate: true }
 );

情况二:监听ref所定义的多个响应式数据
watch([sum1, msg], (newValue, oldalue) => {
  console.log("sum1或msg变化了", newValue, oldalue);
});

情况三:监听reactive所定义的响应式数据的全部属性
	注意:1.此处无法正确的获取oldValue
         2.强制开启了深度监视(deep配置无效)
 watch(person, (newValue, oldalue) => {
   console.log("person变化了", newValue, oldalue);
 });

情况四:监听reactive所定义的一个响应式数据中的某个属性,监听的数据要写成函数的形式将其返回
 watch(
   () => person.name,
   (newValue, oldalue) => {
     console.log("person的name变化了", newValue, oldalue);
   }
 );

情况五:监听reactive所定义的一个响应式数据中的某些属性,监听的数据要写成函数的形式将其返回
 watch([() => person.name, () => person.age], (newValue, oldalue) => {
   console.log("person的name或person的age变化了", newValue, oldalue);
 });

特殊情况
此处由于监听的是reactive所定义的对象中的某个属性,所以配置deep配置有效
watch(
  () => person.job,
  (newValue, oldalue) => {
    console.log("person的job变化了", newValue, oldalue);
  },
  { deep: true }
);

一般监听对象的话是没有办法正确的获取oldValue
watch监听的三个参数:
	第一个:监视的是谁,
	第二个:监视的回调,
	第三个:监视的配置

监听ref定义的数据时

let sum1 = ref(0);
let msg = ref("你好啊");
let person = ref({
  name: "张三",
  age: 18,
  job: {
    j1: { salary: 20 },
  },
});

因为sum1里面存的是基本属性类型的值,所以不用.value进行监听
watch(sum1, (newValue, oldValue) => {
  console.log("newValue", newValue);
  console.log("oldValue", oldValue);
});

watch监听的person.value 即监听的是RefImpl{......} 即RefImpl{......}的value实例对象
即监听的是Proxy

第一种方式
watch(person.value, (newValue, oldValue) => {
  console.log("newValue", newValue);
  console.log("oldValue", oldValue);
});

第二种方式
watch(
  person,
  (newValue, oldValue) => {
    console.log("newValue", newValue);
    console.log("oldValue", oldValue);
  },
  { deep: true }
);

watchEffect()函数
watchEffect()会立即执行一遍回调函数,如果这时函数产生了副作用,Vue 会自动追踪副作用的依赖关系,自动分析出响应源

<template>
    账号:<input type="text" v-model="account">
    <hr>
    员工薪资:<input type="number" v-model="emp.salary">
</template>
<script setup>
// 引入 watch 函数
import { reactive, ref, watchEffect } from 'vue'

// 账号
let account = ref('Abc')
// 员工
let emp = reactive({
    name: 'Jack',
    salary: 7000
})

// 创建成功后立即执行一遍
watchEffect(() => {
   // 此处用到了数据源,如果该数据源的值发生了变化,会重新执行该回调函数
   console.log('账号:' + account.value)
   console.log('员工的薪资:' + emp.salary)
})
</script>

回调的触发时机
默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用;这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。
如果想在侦听器回调中能访问被 Vue 更新之后的DOM,你需要指明flush: ‘post’ 选项,或者你也可以使用更方便的别名watchPostEffect()函数

<script setup>
import { onMounted, reactive, ref, watchEffect, watchPostEffect } from 'vue'

// 账号
let account = ref('Abc')
// 密码
let password = ref('123456')
// 员工
let emp = reactive({
    name: 'Jack',
    salary: 7000
})

// 当视图渲染成功后
onMounted(() => {
   // 侦听账号
   watchEffect(() => {
       console.log('账号:' + account.value)
       // 默认情况下,回调触发机制:在 Dom 更新之前
       console.log(document.getElementById('titleAccount').innerHTML)
   })

   // 侦听密码
   watchEffect(
      () => {
          console.log('密码:' + password.value)
          // 默认情况下,回调函数触发机制:在 Dom 更新之前
          console.log(document.getElementById('titlePassword').innerHTML)
      },
      // 更改回调函数触发机制:在 Dom 更新之后
      { flush: 'post' }
   )

   // 侦听薪资
   watchPostEffect(() => {
      console.log('员工薪资:' + emp.salary)
      // 回调函数的触发机制:在 Dom 更新之后
      console.log(document.getElementById('titleSalary').innerHTML)
   })
})
</script>

watch和watchEffect的对比

watch

1. watch显式指定依赖数据,依赖数据更新时执行回调函数
2. 具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行
(设置immediate: true时可以变为非惰性,页面首次加载就会执行)
3. 监视ref定义的响应式数据时可以获取到原值
4. 既要指明监视的属性,也要指明监视的回调

watchEffect

1. watchEffect自动收集依赖数据,依赖数据更新时重新执行自身
2. 立即执行,没有惰性,页面的首次加载就会执行
3. 无法获取到原值,只能得到变化后的值
4. 不用指明监视哪个属性,监视的回调中用到哪个属性就监视哪个属性
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue 3.0中,watch被重构以提供更灵活和强大的对象监听功能。 在Vue 3.0中,我们可以通过创建一个watcher实例来监听对象的变化。以下是使用watch监听对象的步骤: 首先,我们需要使用`watch`函数来定义一个watcher实例并指定需要监听的对象。例如: ``` const myObject = { firstName: 'John', lastName: 'Doe' } watch(myObject, (newValue, oldValue) => { console.log('Object changed:', newValue, oldValue) }) ``` 在这个例子中,我们创建了一个名为`myObject`的对象,并将其传递给`watch`函数。然后,我们传递了一个回调函数,每当对象发生变化时,这个回调函数就会被调用。回调函数的参数是新值和旧值。 然后,我们可以通过改变对象的属性来测试监听。例如,我们可以使用以下代码来修改`myObject`的`firstName`属性: ``` myObject.firstName = 'Jane' ``` 在控制台中,你将看到输出:`Object changed: { firstName: 'Jane', lastName: 'Doe' } { firstName: 'John', lastName: 'Doe' }`。这表明对象已经发生了变化,并且新值和旧值都被传递给了回调函数。 除了基本的对象监听外,Vue 3.0还提供了更高级的监听选项。例如,我们可以使用`deep`选项来深度监听对象的属性变化,或使用`immediate`选项来立即执行回调函数。 总之,Vue 3.0的watch提供了一种方便的方法来监听对象的变化,并在变化发生时执行特定的操作。无论是简单的对象还是复杂的嵌套对象,watch都能够准确地捕捉到其变化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值