Detailed explanation of Vue3 watch and the difference with vue2watch

watch introduction

watch attribute monitoring is an object, the key is the attribute to be observed, and the value is the corresponding callback function, which is mainly used to monitor the changes of certain specific data, so as to perform some specific business logic operations. Used when performing asynchronous or expensive operations.


Vue2 usage

In the options API of Vue2, watch is a module like methods , in which the corresponding listening events are defined

Monitor basic variables

Ordinary variables that need to be monitored , in the watch module, define a function named after the variable name, like the following count

<template>
  <div>
    <h2>{
    
    { count }}</h2>
    <button @click="count++">+</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  watch: {
  // count 接收一个回调函数,当数据变化时会执行该函数,接收两个参数:
  // 第一个参数是:最新的值 第二个参数是:上一次的值
    count: function(newValue, oldValue) {
      console.log(newValue, oldValue) // 1, 0
    }
  }
};
</script>


listening object

The object that needs to be monitored , define the variable in the watch module, add the deep attribute to realize deep monitoring

<template>
  <div>
    <h2>{
    
    { data.count }}</h2>
    <button @click="data.count++">+</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      data: {
        count: 0
      }
    }
  },
  watch: {
    data: {
      change(newValue,oldValue) {
        console.log(newValue, oldValue)  // 1, 0
      },
      deep: true, // 添加这个属性,当data里面深层嵌套的数据发生变化时也可以执行回调
      immediate: true // 添加这个属性,当界面初始化时会先执行一次
    }
  }
};
</script>

Usage of Vue3

In Vue3's Composition API , watch is called as a function , and the corresponding event logic is defined in the function

Listening base type

<template>
  <div class="card"> 
    <span>{
    
    { count }}</span>
    <button @click="Add">+</button>
  </div>
</template>

<script setup>
import { ref, watch } from "vue";
const count = ref(0);

watch(count, (newValue, oldValue) => {
  console.log('newValue->', newValue);
  console.log('oldValue->', oldValue);
})
const Add = () => {
  count.value++;
}
</script>

Listening to complex types

<template>
  <div>
    <button @click="change">change</button>
  </div>
</template>

<script setup>
import { ref, watch, reactive } from "vue";
const user = reactive({
  name: "jake",
  phone: "10010",
  score: {
    math: 90,
    english: 80,
  },
});
const change = () => {
  user.name = "mike";
};
</script>

There are many situations for complex types of monitoring, the specific content is as follows


Listen to the entire object (used more)

// 监听整个对象;
watch(user, (newValue, oldValue) => {
  console.log("newValue->", newValue);
  console.log("oldValue->", oldValue);
});

Its first parameter is the object user to be monitored directly. When monitoring the entire object, as long as the object has any modification, the watch method will be triggered. Whether its sub-property changes (such as user.name), or grandchildren property changes (such as user.score.math), the watch method will be triggered. Deep monitoring is enabled by default, and cannot be turned off by configuring deep: false

Note: The data (object) defined by reactive cannot get the correct oldValue (the last value), and the print results are the same



Listen to a property in an object

// 监听对象单个属性
watch(
  () => user.name,
  (newValue, oldValue) => {
    console.log("newValue->", newValue);
    console.log("oldValue->", oldValue);
  }
);

As above code, monitor the name attribute of the user object, then only when the name attribute of the user object changes, the watch method will be triggered, and other attribute changes will not trigger the watch method. Note that the first parameter at this point is an arrow function .

Note: This way can get the correct oldValue (the last value), pay attention to the difference from the above


listener object subproperties

// 监听对象子属性
watch(
  () => ({ ...user }),
  (newValue, oldValue) => {
    console.log("newValue->", newValue);
    console.log("oldValue->", oldValue);
  }
);

In this case, the watch method will only be triggered when the user's sub-attributes (name, phone) change. Grandchildren attributes, great-grandchildren attributes... will not trigger the watch method if they change. That is to say, the watch method will not be triggered when you modify user.score.math or user.score.english.

Note: This method can get the correct oldValue (the last value), but it is slightly different from the above



Listen to all properties of the object

// 监听整个对象,使用 deep 属性
watch(
  () => user,
  (newValue, oldValue) => {
    console.log("newValue->", newValue);
    console.log("oldValue->", oldValue);
  },
  { deep: true }
);

This is equivalent to monitoring the entire object (the effect is the same as the first one above). But the implementation method is different from the first one above . Here we can see that the first parameter is an arrow function, and there is a third parameter { deep: true } . When the third parameter { deep: true } is added, it will not only monitor the sub-properties of the object, but also monitor the grandson properties, great-grandson properties...

Note: This is the same as the first case, the correct oldValue (the last value) cannot be obtained, and the printing results are the same



Usually, to implement all the properties of the monitoring object, the first method will be used, because the first method is simple to code, and the first parameter can be passed directly to the object. Although the oldValue cannot be obtained, it is not a big problem.


Combined monitoring

Combined monitoring means that if you want to monitor the name attribute of the user object and the basic type count at the same time, as long as any of them changes, the watch method will be triggered. to be used in certain circumstances

const count = ref(0);
const user = reactive({
  name: "jake",
  phone: "10010",
  score: {
    math: 90,
    english: 80,
  },
});
// 组合监听
watch([() => user.name, count], ([newName, newCount], [oldName, oldCount]) => {
  console.log("newName->", newName);
  console.log("oldName->", oldName);
  console.log("newCount->", newCount);
  console.log("oldCount->", oldCount);
});

注意,此时的第一个参数是一个数组, 且第二参数箭头函数的参数也是数组的形式。


Vue 2 Vue3 小区别

在 Vue2 的 options API 中, watchmethods 一样作为一个模块,如果要监听多个变量,要在其中一个一个定义相应的监听事件

VUE3 的 Composition API可以多次使用 watch 方法,通过多个watch 方法来监听多个对象。

Vue2

watch: {
    count () {
      // 逻辑代码
    },
   user: {
    name() {
       // 逻辑代码
        }
    }
}

Vue3

watch(count, () => {})
watch(() => user.name, () => {})

computed和watch的区别

通俗来讲,既能用 computed 实现又可以用 watch 监听来实现的功能,推荐用 computed, 重点在于 computed 的缓存功能 ,computed 计算属性是用来声明式的描述一个值依赖了其它的值,当所依赖的值或者变量 改变时,计算属性也会跟着改变; watch 监听的是已经在 data 中定义的变量,当该变量变化时,会触发 watch 中的方法。

watch

watch 属性监听 是一个对象,键是需要观察的属性,值是对应回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,监听属性的变化,需要在数据变化时执行异步或开销较大的操作时使用

computed

computed 计算属性 属性的结果会被缓存,当 computed 中的函数所依赖的属性没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取。除非依赖的响应式属性变化时才会重新计算,主要当做属性来使用 computed 中的函数必须用 return 返回最终的结果, computed 更高效,优先使用。data 不改变,computed 不更新。

适用场景

computed:当一个属性多个属性影响的时候使用,例:购物车商品结算功能

watch: 当一条数据影响多条数据的时候使用,例:搜索数据


文章如有错误,恳请大家提出问题,本人不胜感激 。 不懂的地方可以评论,我都会 一 一 回复

文章对大家有帮助的话,希望大家能动手点赞鼓励,大家未来一起努力 长路漫漫,道阻且长

Guess you like

Origin blog.csdn.net/qq_52855464/article/details/129642441