目錄
#watch與watchEffect的比較
watch
watchEffect與computed有點像:
首頁 web前端 Vue.js 一文詳解Vue中watch和watchEffect的區別

一文詳解Vue中watch和watchEffect的區別

Aug 09, 2022 pm 03:20 PM
vue watch watcheffect

前言

watch函數與watchEffect函數都是監聽器,在寫法和用法上有一定區別,是同一功能的兩種不同形態,底層都是一樣的。 【相關推薦:vue.js影片教學

#watch與watchEffect的比較

watch

  • ##watch明確指定依賴數據,依賴數據更新時執行回呼函數
  • 具有一定的惰性lazy 第一次頁面展示的時候不會執行,只有數據變化的時候才會執行(設定
  • immediate: true時可以變成非惰性,頁面首次載入就會執行)
  • 監視ref定義的響應式資料時可以取得原值
  • 既要指明監視的屬性,也要指明監視的回呼
watchEffect

  • watchEffect自動收集依賴數據,依賴數據更新時重新執行自身

  • 立即執行,沒有惰性,頁面的首次載入就會執行

  • 無法取得原值,只能得到變化後的值

  • 不用指明監視哪個屬性,監視的回呼中用到哪個屬性就監視哪個屬性

深度解析watch函數

watch函數有兩個小坑:

    ##監視reactive定義的響應式數據(該資料為一個對象,因為reactive只能定義數組或對象類型的響應式)時:oldValue無法正確獲取,會強制開啟深度監視,deep配置不生效。
  • 監視reactive定義的響應式資料中的某個屬性時,且該屬性是對象,那麼此時deep配置生效。
具體的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>
登入後複製

watch取消監聽

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總是會調用一次
  • 範例:
<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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vue中怎麼用bootstrap vue中怎麼用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分為五個步驟:安裝 Bootstrap。在 main.js 中導入 Bootstrap。直接在模板中使用 Bootstrap 組件。可選:自定義樣式。可選:使用插件。

vue怎麼給按鈕添加函數 vue怎麼給按鈕添加函數 Apr 08, 2025 am 08:51 AM

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

vue中的watch怎麼用 vue中的watch怎麼用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 選項允許開發者監聽特定數據的變化。當數據發生變化時,watch 會觸發一個回調函數,用於執行更新視圖或其他任務。其配置選項包括 immediate,用於指定是否立即執行回調,以及 deep,用於指定是否遞歸監聽對像或數組的更改。

vue多頁面開發是啥意思 vue多頁面開發是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

vue返回上一頁的方法 vue返回上一頁的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一頁有四種方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 組件window.history.back(),方法選擇取決於場景。

vue.js怎麼引用js文件 vue.js怎麼引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三種:直接使用 &lt;script&gt; 標籤指定路徑;利用 mounted() 生命週期鉤子動態導入;通過 Vuex 狀態管理庫進行導入。

vue遍歷怎麼用 vue遍歷怎麼用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。

vue的div怎麼跳轉 vue的div怎麼跳轉 Apr 08, 2025 am 09:18 AM

Vue 中 div 元素跳轉的方法有兩種:使用 Vue Router,添加 router-link 組件。添加 @click 事件監聽器,調用 this.$router.push() 方法跳轉。

See all articles