ホームページ  >  記事  >  ウェブフロントエンド  >  Vue の watch と watchEffect の違いを説明した記事

Vue の watch と watchEffect の違いを説明した記事

藏色散人
藏色散人転載
2022-08-09 15:20:392519ブラウズ

はじめに

watch 関数と watchEffect 関数はどちらもリスナーです。書き方と使用法にいくつかの違いがあります。これらは同じ関数の 2 つの異なる形式ですが、最下層は同じです。 [関連する推奨事項: vue.js ビデオ チュートリアル ]

watch と watchEffect の比較

watch

  • watch依存データを明示的に指定します。依存データが更新されると、はコールバック関数を実行します。
  • は、ある程度の遅延があります。最初のページ表示時には実行されません。ただし、データが変更された場合にのみ実行されます ( immediate: true を設定すると、非遅延状態になる可能性があり、ページは最初にロードされたときに実行されます)
  • ref
  • 監視対象の属性と監視対象のコールバックの両方を指定する必要があります
##watchEffect

  • watchEffectデータ更新時に依存関係データを自動的に収集自身を再実行

  • 即時慣性はありません。ページが初めて読み込まれるときに実行されます

  • #元の値は取得できません。変更された値のみ
  • ##どの属性を監視するかを指定する必要はありません。監視コールバックで使用される属性が監視されます
  • watch 関数
watch 関数には 2 つの落とし穴があります。

reactive で定義された応答データの監視 (reactive は配列または配列の応答のみを定義できるため、データはオブジェクトです)オブジェクト タイプ): oldValue を正しく取得できず、詳細な監視が強制的にオンになり、詳細な構成は有効になりません。
  • reactive で定義された応答データ内の属性を監視し、その属性がオブジェクトである場合、詳細設定が有効になります。
  • #watch 関数の具体的な使用法は、詳細なコメントとともに次のコードに反映されています。
<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>

監視キャンセル監視

const stop1 = watch(
  [() => nameObj.name, () => nameObj.name],
  ([curName, curEng], [prevName, curEng]) => {
    console.log(curName, curEng, "----", prevName, curEng);
    setTimeout(() => {
      stop();
    }, 5000);
  });

watchEffect 関数の詳細な分析

関数の使用法は、詳細なコメントとともに次のコードに示されています。

#
<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 キャンセル監視

const stop = watchEffect(() => {
  console.log(nameObj.name);
  setTimeout(() => {
    stop();
  }, 5000);});
watchEffect と computed

watchEffect は computed に少し似ています:

ただし、computed は計算された値に焦点を当てます。 (コールバック関数の戻り値)なので、戻り値を記述する必要があります。

  • そして、watchEffect は処理 (コールバック関数の関数本体) に重点を置くため、戻り値を記述する必要がありません。

  • computed は、値が使用されていない場合には呼び出されませんが、watchEffect は常に 1 回呼び出されます。

  • 例:

    <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>

以上がVue の watch と watchEffect の違いを説明した記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。