Vue.js框架:vue3版本里数据变化监听watch和watchEffect的使用

发布时间 2023-10-20 11:24:02作者: 我命倾尘

一、监听方法

  vue3中定义的变量默认不是响应式的,所以只能监听用refreactive定义的数据和变量。

  监听前要确保引入相关依赖ref、reactive、watch:

    <script setup lang="ts">
    import { ref,watch,reactive } from 'vue';

    </script>

  1、监听单个值的变化:

  通过ref定义一个变量testText,并将这个值和文本框绑定,对这个值进行监听:

    <script setup lang="ts">
    import { ref,watch,reactive } from 'vue';

    let testText = ref<string>("testText");

    watch(testText,(newValue,OldValue) => {
      console.log(newValue);
      console.log(OldValue);
    });
    </script>

    <template>
        <input type="text" v-model="testText" />
    </template>

  

  2、监听多个值的变化:

  通过ref定义两个变量testText、testContent,并将这两个值和文本框绑定,对这两个值进行监听:

    <script setup lang="ts">
    import { ref,watch,reactive } from 'vue';

    let testText = ref<string>("testText");
    let testContent = ref<string>("testContent");

    watch([testText,testContent],(newValue,OldValue) => {
      console.log(newValue);
      console.log(OldValue);
    });
    </script>

    <template>
      <input type="text" v-model="testText" />
      <input type="text" v-model="testContent" />
    </template>

  多个监听值的时候,输出的监听结果新值和旧值也是多个:

  

  3、监听表单变化:

  通过reactive创建一个表单testText ,并将其内部的属性title与文本框绑定,对表单整体进行监听:

    <script setup lang="ts">
    import { ref,watch,reactive } from 'vue';

    let testText = reactive({
      title:"标题"
    });

    watch(testText,(newValue,OldValue) => {
      console.log(newValue);
      console.log(OldValue);
    });
    </script>

    <template>
      <input type="text" v-model="testText.title" />
    </template>

  得到的结果如下:

  

  注:从这里可以看出,当表单的内部属性发生变化后,监听表单整体时是拿不到修改前的值。

  而且监听表单整体时默认watch自动开启了deep属性,即深度监听。

  4、监听表单下的属性值:

  通过reactive创建一个表单testText ,并将其内部的属性title与文本框绑定,对表单内部的title属性进行单独监听:

    <script setup lang="ts">
    import { ref,watch,reactive } from 'vue';

    let testText = reactive({
      title:"标题"
    });

    watch(() => testText.title,(newValue,OldValue) => {
      console.log(newValue);
      console.log(OldValue);
    });
    </script>

    <template>
      <input type="text" v-model="testText.title" />
    </template>

  得到的结果如下:

  

  这次新值和旧值都打出来了,单独监听的话是可以取到旧值的。

  注:监听内部的时候需要使用  () =>  来指向,如果是独立的单个定义值的话,也可以通过这个前缀加属性名称加.value来监听。

  5、监听多层嵌套表单下的表单:

  通过reactive创建一个表单testText ,并将其内部的表单form里的title属性值与文本框绑定,对表单内部的form表单整体进行监听:

    <script setup lang="ts">
    import { ref,watch,reactive } from 'vue';

    let testText = reactive({
      form:{
        title:"标题"
      }
    });

    watch(() => testText.form,(newValue,OldValue) => {
      console.log(newValue);
      console.log(OldValue);
    },{ deep:true });
    </script>

    <template>
      <input type="text" v-model="testText.form.title" />
    </template>

  这里就要在监听时候加上deep属性并配置为true,通过深度监听才能监听到内部表单的变化,而且因为是监听的表单,同样无法拿到旧值。

  

二、监听属性

  1、是否立即执行(immediate):

  这是个布尔类型值,true和false代表是否开启该属性。默认为false即关闭,而开启和关闭的区别在于,监听是否要在初始化的时候触发

  例如,定义一个字符串值的时候,默认为”初始值”,然后将其修改为”修改值”,此时会产生差异:

  true:会先在初始化为“初始值”时触发一次监听,再在值调整为“修改值”时触发第二次监听。

  false:初始化为“初始值”时不触发,在值调整为“修改值”时触发第一次监听。

  2、是否深度监听(deep):

  主要用于监听多层嵌套的表单内部表单,默认为false关闭,需要监听时属性可以设置为true。

三、无指向监听

  watch的监听需要三个参数,分别是监听的数据内容、监听回调函数方法、监听配置属性

  而watchEffect不同,它不需要指定监听的数据内容,会根据回调函数方法里用到的数据,自动去监听这些内容,且immediatedeep两个属性都默认为开启状态

    <script setup lang="ts">
    import { ref,watch,reactive, watchEffect } from 'vue';

    let testText = reactive({
      form:{
        title:"watchEffect"
      }
    });

    watchEffect(() => {
      console.log(testText.form.title);
    });
    </script>

    <template>
      <input type="text" v-model="testText.form.title" />
    </template>

  得到的结果如下: