Home  >  Article  >  Web Front-end  >  How to use watch under vue3

How to use watch under vue3

WBOY
WBOYforward
2023-05-17 12:14:262961browse

    Since it is data monitoring, what is monitored is its changes. Then you need to be able to capture its changes, so the monitored data must be responsive data

    watch(WatcherSource, Callback, [WatchOptions])
    Parameters:
    WatcherSource: Want to monitor responsive data.
    Callback: Callback function to be executed, input parameters (newValue, oldValue).
    [WatchOptions]: deep, immediate, and flush are optional.

    For parameter configuration of WatchOptions:

    deep: When it is necessary to deeply monitor reference type data such as objects, set deep: true, and the default value is false.
    immediate: By default, watch is lazy. When immediate: true is set, watch will execute the callback function once immediately during initialization.
    flush: Control the execution timing of the callback function. It can be set to pre, post or sync.
    Pre: Default value. When the monitored value changes, the callback function is executed first (executed before the DOM is updated).
    Post: After the DOM update and rendering is completed, execute the callback function.
    sync: Once the monitored value changes, the callback function is executed synchronously (it is recommended to use it sparingly).

    1. Monitoring a single data ref

    const count = ref(1);
    watch(count, (newValue, oldValue) => {
      console.log('值发生了变更', newValue, oldValue);
    });

    can obtain the new value and the old value.

    Second, monitor reference type data ref: deep monitoring

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

    Even if the entire array is monitored as a reference data type, changes to one of its internal items will not be observed. So the code in the watch is not executed.

    1, reference type ref direct deep monitoring

    At this time, you need to use deep monitoring: deep:true

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

    The value has changed Proxy {a: 5, b: 2} Proxy {a: 5, b: 2}

    It can be noted that the need for deep monitoring is the reference data type itself, not the attributes in it . Moreover, he can only get the new value, but not the old value.

    2, reference type ref deep copy deep monitoring

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

    In this way, you can make a deep copy of the reference type data source of watch to complete the acquisition of the old and new values:

    The value has changed {a: 5, b: 2} {a: 1, b: 2}

    3, monitor single data: reactive

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

    here Mainly () => single.count, what is monitored is the count in single, and the callback function will be triggered only when this attribute changes. In this case, it is possible to obtain the old and new values.

    Fourth, monitor reference type data: 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 &#39;vue&#39;;
    const single = reactive({ count: 1, test: { a: 1, b: 2 } });
    const handleClick = function () {
      single.test.a++;
    };
    watch(
      single,
      (newValue, oldValue) => {
        console.log(&#39;值发生了变更&#39;, newValue, oldValue);
      },
      { immediate: true }
    );
    </script>

    reactive data, it has no effect whether deep: true is used or not. If an attribute in single changes, it can be monitored. Then execute the callback function.

    The difference from No. 3 is that only new values ​​can be obtained in this case.

    5, immediate: true

    By default, watch is lazy. When we setimmediate: true, watch will execute the callback immediately during initialization. function.

    const count = ref(1);
    const handleClick = function () {
      count.value++;
    };
    watch(
      count,
      (newValue, oldValue) => {
        console.log(&#39;值发生了变更&#39;, newValue, oldValue);
      },
      { deep: true, immediate: true }
    );

    Six, monitor multiple data sources

    const count = ref(1);
    const double = ref(2);
    const handleClick = function () {
      count.value++;
      double.value++;
    };
    watch(
      [count, double],
      (newValue, oldValue) => {
        console.log(&#39;值发生了变更&#39;, newValue, oldValue);
      },
      { deep: true, immediate: true }
    );

    If two values ​​change at the same time, the watch callback function will be triggered only once, and the watch will be triggered for each value change. Callback.

    If you want to trigger a callback when changing one cell of data, you can add nextTick between the two data changes.

    Seven, flush configuration

    1. By default, the callback function is called before the DOM rendering is completed.

    The callback function takes precedence over the DOM update execution. When the listening value changes, flush The default is pre. This means that if there is a DOM-related operation in the callback function and immediate: true is configured in the parameter, an error will be reported because the DOM has not been rendered at this time and the DOM cannot be obtained.

    Next look at the code:

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

    The result obtained:

    --- 1 value has changed 2 1

    In the callback function, the new value has become 2, but the DOM obtained is still the previous one. By default, the flush value is pre. When the value changes, the callback function will be triggered before the DOM is updated.

    2, flush: 'post’Execute the callback function

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

    after the dom rendering is completed. The result obtained:

    --- 2 value has changed 2 1

    When the callback function is called, the DOM has been updated. The DOM obtained at this time is the DOM that has been updated after the data has been changed.

    The above is the detailed content of How to use watch under vue3. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete