Maison  >  Article  >  interface Web  >  Un article expliquant la différence entre watch et watchEffect dans Vue

Un article expliquant la différence entre watch et watchEffect dans Vue

藏色散人
藏色散人avant
2022-08-09 15:20:392536parcourir

Avant-propos

La fonction watch et la fonction watchEffect sont toutes deux des auditeurs. Il existe certaines différences dans l'écriture et l'utilisation. Ce sont deux formes différentes de la même fonction, mais la couche inférieure est la même. [Recommandations associées : Tutoriel vidéo vue.js]

Comparaison entre watch et watchEffect

watch

  • watch Spécifiez explicitement les données dépendantes et lorsque les données dépendantes sont mises à jourwatch显式指定依赖数据,依赖数据更新时执行回调函数
  • 具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行(设置immediate: true时可以变为非惰性,页面首次加载就会执行)
  • 监视ref定义的响应式数据时可以获取到原值
  • 既要指明监视的属性,也要指明监视的回调

watchEffect

  • watchEffectexécutez la fonction de rappel

    Il a un certain degré de paresse. Il ne sera pas exécuté lorsque la page est affichée pour la première fois. Il ne sera exécuté que lorsque les données changent (il peut devenir non paresseux lors de la définition de immediate: true. , et il sera exécuté lors du premier chargement de la page).
  • Vous pouvez obtenir la valeur d'origine lors de la surveillance des données réactives définies par ref

  • Il est nécessaire de spécifier à la fois l'attribut surveillé et le rappel surveillé
  • watchEffect
  • watchEffect est automatiquement collecté. Données dépendantes, lorsque les données dépendantes sont mises à jour

    se réexécute

s'exécute immédiatement, il n'y a pas d'inertie, il sera exécuté lors du premier chargement de la page

  • La valeur d'origine ne peut pas être obtenue, seule la valeur modifiée

  • Il n'est pas nécessaire de spécifier quel attribut surveiller, il suffit de surveiller quel attribut est utilisé dans le rappel de surveillance

Analyse approfondie de la fonction montre

La fonction montre présente deux écueils :

Surveillance des données réactives définies par réactif ( Les ​​données sont un objet, car réactif ne peut définir que le réponse du type de tableau ou d'objet) : oldValue ne peut pas être obtenu correctement, la surveillance approfondie sera forcée d'être activée et la configuration approfondie ne prendra pas effet.

Lors de la surveillance d'un certain attribut dans les données réactives définies par réactif et que l'attribut est un objet, la configuration approfondie prendra effet.

L'utilisation spécifique de la fonction watch est reflétée dans le code suivant, avec des commentaires détaillés

<template>
    <div>
        <h2>当前求和为:{{sum}}</h2>
        <button @click="sum++">点我+1</button>
        <hr>
        <h2>当前的信息为:{{msg}} </h2>
        <!-- 点击button拼接! -->
        <button @click="msg+=&#39;!&#39;">修改数据</button>
        <hr>
        <h2>姓名:{{person.name}}</h2>
        <h2>年龄:{{person.age}}</h2>
        <h2>薪资:{{person.job.j1.salary}}</h2>
        <button @click="person.name+=&#39;~&#39;"> 修改姓名</button>
        <button @click="person.age++"> 增长年龄</button>
        <button @click="person.job.j1.salary++"> 增长薪资</button>
    </div>
</template>

<script>
import {ref,reactive,watch,watchEffect} from &#39;vue&#39;
export default {
   name:&#39;demo&#39;,
   setup(){
       //数据
       let sum = ref(0)
       let msg = ref(&#39;hello&#39;)
       let person = reactive({
           name:&#39;zhangsan&#39;,
           age:&#39;18&#39;,
           job:{
               j1:{
                   salary:20
               }
           }
       })
       //监视(三个参数,第一个是监视的对象,第二个是监视的回调函数,第三个是监视的配置)

       //情况一:监视ref所定义的一个响应式数据
       watch(sum,(newValue,oldValue)=>{
           console.log(&#39;sum的值变化了&#39;,newValue,oldValue)
       },{immediate:true,deep:true})
       //immediate的值为true时表示非惰性的立即执行的(默认情况下是false)
       //deep深层次触发(此处设置deep无意义)

       //情况二:监视ref所定义的多个响应式数据,写成数组的形式

       watch([sum,msg],(newValue,oldValue)=>{
           console.log(&#39;sum或者msg变了&#39;,newValue,oldValue)
       })

       //情况三:监视reactive所定义的响应式数据
                //若监视的是reactive定义的响应式数据,则无法正确获得oldValue
                //若监视的是reactive定义的响应式数据,则watch会强制开启深度监视

        //我们发现改变person的任意一个属性都会被监视到
        watch(person,(newValue,oldValue)=>{
            console.log(&#39;person改变了&#39;,newValue,oldValue)
        }) 
        
        //我们尝试设置deep:false,关闭深度监听(目的:改变job的值不会被watch监听到)
        //但是我们发现deep:false并没有生效,原因是此时watch监视的是reactive定义的响应式对象,默认强制开启了深度监听
        watch(person,(newValue,oldValue)=>{
            console.log(&#39;person改变了&#39;,newValue,oldValue)
        },{deep:false}) 
        


      //情况四:监视reactive所定义的响应式数据中的某个属性
       watch(()=>person.name,(newValue,oldValue)=>{
            console.log(&#39;person的job改变了&#39;,newValue,oldValue)
        })
         watch(()=>person.age,(newValue,oldValue)=>{
            console.log(&#39;person的job改变了&#39;,newValue,oldValue)
        })
        watch(()=>person.job,(newValue,oldValue)=>{
            console.log(&#39;person的job改变了&#39;,newValue,oldValue)
        })
        //从上边我们发现改变name,age都会触发监听,但是改变job不会
        //这是因为name和age属性的值只是一个简单的基本类型数据,
        //而job属性的值是一个对象,比较深,想要监视到,就要开启深度监视,程序如下:
        watch(()=>person.job,(newValue,oldValue)=>{
            console.log(&#39;person的job改变了&#39;,newValue,oldValue)
        },{deep:true})//此时job改变,会被监视到,此处的deep配置生效
        //需要和情况三进行区分,此处watch监视的是reactive所定义的对象中的某个属性,而情况三watch监视的是reactive所定义的对象

      //情况五:监视reactive所定义的响应式数据中的某些属性,写成数组的形式
        watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
            console.log(&#39;person的name或age改变了&#39;,newValue,oldValue)
        })

       //返回一个对象(常用)
       return{
           sum,
           msg,
           person
       }
   }
}
</script>

surveillance d'annulation de la montre
  • const stop1 = watch(
      [() => nameObj.name, () => nameObj.name],
      ([curName, curEng], [prevName, curEng]) => {
        console.log(curName, curEng, "----", prevName, curEng);
        setTimeout(() => {
          stop();
        }, 5000);
      });

    Analyse approfondie de la fonction watchEffect

  • L'utilisation de la fonction est affiché dans le code suivant, avec des commentaires détaillés :

    <template>
        <div>
            <h2>当前求和为:{{sum}}</h2>
            <button @click="sum++">点我+1</button>
            <hr>
            <h2>当前的信息为:{{msg}} </h2>
            <!-- 点击button拼接! -->
            <button @click="msg+=&#39;!&#39;">修改数据</button>
            <hr>
            <h2>姓名:{{person.name}}</h2>
            <h2>年龄:{{person.age}}</h2>
            <h2>薪资:{{person.job.j1.salary}}</h2>
            <button @click="person.name+=&#39;~&#39;"> 修改姓名</button>
            <button @click="person.age++"> 增长年龄</button>
            <button @click="person.job.j1.salary++"> 增长薪资</button>
        </div>
    </template>
    
    <script>
    import {ref,reactive,watch,watchEffect} from &#39;vue&#39;
    export default {
       name:&#39;demo&#39;,
       setup(){
           //数据
           let sum = ref(0)
           let msg = ref(&#39;hello&#39;)
           let person = reactive({
               name:&#39;zhangsan&#39;,
               age:&#39;18&#39;,
               job:{
                   j1:{
                       salary:20
                   }
               }
           })
    //watchEffect函数内部所指定的回调中用到的数据只要发生变化,就会重新执行回调
    //只有一个参数,就是回调
        watchEffect(()=>{
            const x1 = sum.value//因为sum是ref定义的响应式数据,需要使用.value调用
            const x2 = person.age
            console.log(&#39;watchEffect配置的回调执行了&#39;)
        })
               return{
               sum,
               msg,
               person
           }
       }
    }
    </script>
  • watchEffect annule la surveillance

    const stop = watchEffect(() => {
      console.log(nameObj.name);
      setTimeout(() => {
        stop();
      }, 5000);});
  • watchEffect et calculée

watchEffect et calculé sont un peu comme :

🎜🎜🎜Mais calculé se concentre sur la valeur calculée (le retour valeur de la fonction de rappel), la valeur de retour doit donc être écrite . 🎜🎜🎜🎜Et watchEffect accorde plus d'attention au processus (le corps de la fonction de rappel), il n'est donc pas nécessaire d'écrire une valeur de retour. 🎜🎜🎜🎜computed ne sera pas appelé si la valeur n'est pas utilisée, mais watchEffect sera toujours appelé une fois🎜🎜🎜🎜Exemple : 🎜
<template>
    <div>
        <h2>当前求和为:{{sum}}</h2>
        <button @click="sum++">点我+1</button>
        <hr>
        <h2>当前的信息为:{{msg}} </h2>
        <!-- 点击button拼接! -->
        <button @click="msg+=&#39;!&#39;">修改数据</button>
        <hr>
        <h2>姓名:{{person.name}}</h2>
        <h2>年龄:{{person.age}}</h2>
        <h2>薪资:{{person.job.j1.salary}}</h2>
        <button @click="person.name+=&#39;~&#39;"> 修改姓名</button>
        <button @click="person.age++"> 增长年龄</button>
        <button @click="person.job.j1.salary++"> 增长薪资</button>
    </div>
</template>

<script>
import {ref,reactive,watch,watchEffect, computed} from &#39;vue&#39;
export default {
   name:&#39;demo&#39;,
   setup(){
       //数据
       let sum = ref(0)
       let msg = ref(&#39;hello&#39;)
       let person = reactive({
           name:&#39;zhangsan&#39;,
           age:&#39;18&#39;,
           job:{
               j1:{
                   salary:20
               }
           }
       })
       let person1 = reactive({
           firstName:&#39;张&#39;,
           lastName:&#39;三&#39;
       })
       //computed
       //计算属性——简写(没有考虑计算属性被修改的情况)
       person1.fullName = computed(()=>{
           //必须含有返回值
           return person1.firstName+&#39;-&#39;+person1.lastName
       })

       //计算属性——完整写法(考虑读和写)
       person1.fullName = computed({
           //必须含有返回值
           get(){
               return person1.firstName+&#39;-&#39;+person1.lastName
           },
           set(value){
               const nameArr = value.split(&#39;-&#39;)
               person1.firstName = nameArr[0]
               person1.lastName = nameArr[1]
           }
       })
       //watchEffect
        //可以不写给返回值
        watchEffect(()=>{
            const x1 = sum.value//因为sum是ref定义的响应式数据,需要使用.value调用
            const x2 = person.age
            console.log(&#39;watchEffect配置的回调执行了&#39;)
        })
         return{
           sum,
           msg,
           person,
           person1
       }
   }
}
</script>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer