setup中使用侦听器

在 vue2 中可以通过 watch 选项来侦听 data、props的数据变化,当数据变化时执行某一些操作。

在 Composition API 中我们可以使用 watchEffect、watch 来完成响应式数据的侦听

    watchEffect 用于自动收集响应式数据的依赖;
    watch 需要手动指定侦听的数据源;

watchEffect 自动监听

  • 首先,watchEffect 传入的函数会被立即执行一次,并且在执行的过程中会收集依赖
  • 其次,只有收集的依赖发生变化,watchEffect传入的函数才会再次执行
<template>
  <div>
    <h3>{{ count }}</h3>
    <button @click="increment">+1</button>
  </div>
</template>

<script>
import { ref, watchEffect } from "vue";
export default {
  setup() {
    let count = ref(0);
    const name = ref("zk");
    const age = ref(23);

    const stopWatch = watchEffect(
      (onInvalidate) => {
        console.log(
          `watchEffect执行~, 
          name:${name.value}, age:${age.value},count:${count.value}`
        );
        /*
          我们在开发中可能会遇到在侦听器中去执行网络请求,
          但是当网络请求还没有达到的时候,我们想停止侦听器或者侦听器被再次执行了,
          那么上一次的网络请求应该被取消掉,这个时候就需要清除上一次的副作用
        */
        const timer = setTimeout(() => {
          console.warn("模拟网络请求");
        }, 2000);
        // 侦听器被再次执行或者停止侦听器时的回调
        onInvalidate(() => {
          clearTimeout(timer);
        });
      },
      {
        // 设置watchEffect的执行时机
        /* 
          pre : 默认值,在元素挂载或者更新之前执行
          post: 在元素挂载之后执行
          sync: 强制效果始终同步触发,然而这是低效的,应该避免使用
        */
        flush: "post",
      }
    );

    const increment = () => {
      count.value++;
      // 如果想要在某个条件下停止侦听,可以调用watchEffect的返回值
      if (count.value >= 5) {
        stopWatch();
      }
    };
    return {
      count,
      increment,
    };
  },
};
</script>

 

watch手动监听

    与 watchEffect 相比,watch 允许我们:

        懒执行副作用(不会立即执行一次)
        更具体的说明当哪些状态发生变化时,出发侦听器的执行
        访问侦听器数据变化前后的值

    watch侦听函数的数据源有两种类型:

        一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
        直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref)

<template>
  <div>
    <h2>{{ state.name }}</h2>
    <button @click="changeName">改变名字</button>
  </div>
</template>

<script>
import { ref, reactive, watch } from "vue";
export default {
  setup() {
    const state = reactive({
      name: "zk",
      age: 23,
    });
    const name = ref("kobe");
    // 侦听单个数据源
    /* 
      watch 侦听函数的数据源有两种类型:

    */
    watch(
      () => state.name,
      (newValue, oldValue) => {
        console.log(
          `一个getter函数:newValue:${newValue},oldValue:${oldValue}`
        );
      }
    );

    watch(name, (newValue, oldValue) => {
      console.log(
        `一个可响应式对象:newValue:${newValue},oldValue:${oldValue}`
      );
    });

    // 侦听多个数据源
    watch(
      () => [state.name, state.age],
      (newValue, oldValue) => {
        console.log(`多个数据源:newValue:${newValue},oldValue:${oldValue}`);
      }
    );

    // 侦听响应式对象
    /* 
      希望侦听一个数组或者对象,那么可以使用getter函数
      并且对响应式对象进行解构
    */
    const letters = reactive(["abc", "cba", "nba"]);
    watch(
      () => [...letters],
      (newValue, oldValue) => {
        console.log(
          `侦听响应式对象:newValue:${newValue},oldValue:${oldValue}`
        );
      }
    );

    const changeName = () => {
      state.name = "张三";
      name.value = "李四";
      letters.push("ccc");
    };

    return {
      state,
      changeName,
    };
  },
};
</script>

<style scoped>
</style>

 

posted @ 2021-09-30 15:55  熊大大001(前端开发)  阅读(290)  评论(0编辑  收藏  举报