溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

vue3下的watch怎么使用

發(fā)布時間:2023-03-22 15:45:47 來源:億速云 閱讀:237 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下vue3下的watch怎么使用的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    既然是數(shù)據(jù)監(jiān)聽,監(jiān)聽的是它的變化。那么就需要能夠捕獲它的變更,于是監(jiān)聽的數(shù)據(jù)必然要是響應(yīng)式數(shù)據(jù)

    watch(WatcherSource, Callback, [WatchOptions])
    參數(shù):
    WatcherSource:想要監(jiān)聽的響應(yīng)式數(shù)據(jù)。
    Callback:執(zhí)行的回調(diào)函數(shù),入?yún)ⅲ╪ewValue,oldValue)。
    [WatchOptions]:deep、immediate、flush可選。

    對于WatchOptions的參數(shù)配置:

    deep:當需要對對象等引用類型數(shù)據(jù)進行深度監(jiān)聽時,設(shè)置deep: true,默認值是false。
    immediate:默認情況下watch是惰性的,設(shè)置immediate: true時,watch會在初始化時立即執(zhí)行回調(diào)函數(shù)一次。
    flush:控制回調(diào)函數(shù)的執(zhí)行時機,。它可設(shè)置為 pre、post 或 sync。
        pre:默認值,當監(jiān)聽的值發(fā)生變更時,優(yōu)先執(zhí)行回調(diào)函數(shù)(在dom更新之前執(zhí)行)。
        post:dom更新渲染完畢后,執(zhí)行回調(diào)函數(shù)。
        sync:一旦監(jiān)聽的值發(fā)生了變化,同步執(zhí)行回調(diào)函數(shù)(建議少用)。

    一,監(jiān)聽單個數(shù)據(jù)ref

    const count = ref(1);
    watch(count, (newValue, oldValue) => {
      console.log('值發(fā)生了變更', newValue, oldValue);
    });

    可以獲取到新值和舊值。

    二,監(jiān)聽引用類型數(shù)據(jù)ref:深度監(jiān)聽

    const count = ref({
      a: 1,
      b: 2
    });
    const handleClick = function () {
     count.value.a = 5;
    };
    watch(count, (newValue, oldValue) => {
      console.log('值發(fā)生了變更', newValue, oldValue);
    });

    這種情況下,我監(jiān)聽的是整個數(shù)組,它是引用數(shù)據(jù)類型,內(nèi)部的某一項發(fā)生了變更并不會被監(jiān)聽到。所以watch中的代碼并沒有執(zhí)行。

    1,引用類型ref直接深度監(jiān)聽

    此時,就需要使用深度監(jiān)聽:deep:true

    const count = ref({
      a: 1,
      b: 2
    });
    const handleClick = function () {
      count.value.a = 5;
    };
    watch(
      count,
      (newValue, oldValue) => {
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { deep: true }
    );

    值發(fā)生了變更 Proxy {a: 5, b: 2} Proxy {a: 5, b: 2}

    可以注意到的是,深度監(jiān)聽的需要是這個引用數(shù)據(jù)類型自身,而不是其中的屬性。并且,他只能獲取到新值,而獲取不到舊的值。

    2,引用類型ref深拷貝深度監(jiān)聽

    const count = ref({
      a: 1,
      b: 2
    });
    const handleClick = function () {
      count.value.a = 5;
    };
    watch(
      () => {
        return { ...count.value };
      },
      (newValue, oldValue) => {
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { deep: true }
    );

    這樣把watch的引用類型數(shù)據(jù)源深拷貝一份,即可完成對新舊值得獲取:

    值發(fā)生了變更 {a: 5, b: 2} {a: 1, b: 2}

    三,監(jiān)聽單個數(shù)據(jù):reactive

    const single = reactive({ count: 1, test: 2 });
    const handleClick = function () {
      single.count++;
    };
    watch(
      () => single.count,
      (newValue, oldValue) => {
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { immediate: true }
    );

    這里主要是() => single.count,監(jiān)聽的是single中的count,只有這個屬性發(fā)生了變化才會觸發(fā)回調(diào)函數(shù)。這種情況下是可以獲取到新舊值的。

    四,監(jiān)聽引用類型數(shù)據(jù):reactive

    <template>
      <div class="mine-box">
        <div ref="countDom">{{ single.count }}</div>
        <button @click="handleClick">按鈕</button>
      </div>
    </template>
    
    <script setup>
    import { ref, reactive, watch } from 'vue';
    const single = reactive({ count: 1, test: { a: 1, b: 2 } });
    const handleClick = function () {
      single.test.a++;
    };
    watch(
      single,
      (newValue, oldValue) => {
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { immediate: true }
    );
    </script>

    reactive的數(shù)據(jù),用不用deep:true是沒有影響的,single中的一個屬性發(fā)生了變化,都能被監(jiān)聽到,繼而執(zhí)行回調(diào)函數(shù)。

    和三中有所不同的是,這種情況下是只能獲取到新值的。

    五,immediate: true

    默認情況下watch是惰性的,當我們設(shè)置immediate: true時,watch會在初始化時立即執(zhí)行回調(diào)函數(shù)。

    const count = ref(1);
    const handleClick = function () {
      count.value++;
    };
    watch(
      count,
      (newValue, oldValue) => {
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { deep: true, immediate: true }
    );

    六,監(jiān)聽多個數(shù)據(jù)源

    const count = ref(1);
    const double = ref(2);
    const handleClick = function () {
      count.value++;
      double.value++;
    };
    watch(
      [count, double],
      (newValue, oldValue) => {
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { deep: true, immediate: true }
    );

    有一個值發(fā)生了變更,則會觸發(fā)watch,如果兩個值同時發(fā)生變更,同樣只是觸發(fā)一次watch的回調(diào)函數(shù)。

    如果想變更一格數(shù)據(jù)就觸發(fā)一次回調(diào),可以在兩個數(shù)據(jù)變更中間加下nextTick。

    七,flush的配置

    1,默認情況下在dom渲染完畢前調(diào)用回調(diào)函數(shù)

    默認情況下,flush的值是pre,當監(jiān)聽的值發(fā)生變更時,優(yōu)先執(zhí)行回調(diào)函數(shù)(在dom更新之前執(zhí)行)。這就意味著,如果在回調(diào)函數(shù)中有相關(guān)dom的操作,而參數(shù)里面配置了immediate:true,則會報錯,因為這個時候dom還沒有被渲染,是獲取不到dom的。

    接下來看下代碼:

    <template>
      <div class="mine-box">
        <div ref="countDom">{{ count }}</div>
        <button @click="handleClick">按鈕</button>
      </div>
    </template>
    
    <script setup>
    import { ref, watch } from 'vue';
    const count = ref(1);
    const countDom = ref(null);
    const handleClick = function () {
      count.value++;
    };
    watch(
      count,
      (newValue, oldValue) => {
        console.log('---', countDom.value.textContent);
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { deep: true }
    );
    </script>

    得到的結(jié)果:

    --- 1值發(fā)生了變更 2 1

    可以看到,回調(diào)函數(shù)中新的值已經(jīng)變成了2,而獲取到的dom還是之前的。說明默認情況下,flush的值是pre,當有值變更時,是在dom更新之前觸發(fā)回調(diào)函數(shù)的執(zhí)行。

    2,flush: 'post&rsquo;在dom渲染完畢后執(zhí)行回調(diào)函數(shù)

    <template>
      <div class="mine-box">
        <div ref="countDom">{{ count }}</div>
        <button @click="handleClick">按鈕</button>
      </div>
    </template>
    
    <script setup>
    import { ref, watch } from 'vue';
    const count = ref(1);
    const countDom = ref(null);
    const handleClick = function () {
      count.value++;
    };
    watch(
      count,
      (newValue, oldValue) => {
        console.log('---', countDom.value.textContent);
        console.log('值發(fā)生了變更', newValue, oldValue);
      },
      { deep: true, flush: 'post' }
    );
    </script>

    得到的結(jié)果:

    --- 2值發(fā)生了變更 2 1

    可以看到,是在dom更新完畢之后才調(diào)用的回調(diào)函數(shù),這時候獲取到的dom是數(shù)據(jù)變更后更新完畢的dom。

    以上就是“vue3下的watch怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI