Vue3_11(Composition API) computed | watchEffect | Watch

响应式计算和侦听 | Vue.js https://v3.cn.vuejs.org/guide/reactivity-computed-watchers.html#%E8%AE%A1%E7%AE%97%E5%80%BC

computed

方式一:接收一个getter函数,并为 getter 函数返回的值,返回一个不变的 ref 对象;
方式二:接收一个具有 get 和 set 的对象,返回一个可变的(可读写)ref 对象;

// 1.用法一: 传入一个getter函数
      // computed的返回值是一个ref对象
      const fullName = computed(() => firstName.value + " " + lastName.value);

      // 2.用法二: 传入一个对象, 对象包含getter/setter
      const fullName = computed({
        get: () => firstName.value + " " + lastName.value,
        set(newValue) {
          const names = newValue.split(" ");
          firstName.value = names[0];
          lastName.value = names[1];
        }
      });

watchEffect 自动收集响应式数据的依赖

首先,watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;其次,只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行

获取watchEffect的返回值函数,调用该函数即可停止侦听

const stop = watchEffect(() => {
        console.log("name:", name.value, "age:", age.value);
});

const changeAge = () => {
        age.value++;
        if (age.value > 25) {
          stop();
        }
}

给watchEffect传入的函数被回调时,其实可以获取到一个参数:onInvalidate

  当副作用即将重新执行 或者 侦听器被停止(如果在 setup() 或生命周期钩子函数中使用了 watchEffect,则在组件卸载时)时会执行该函数传入的回调函数
  我们可以在传入的回调函数中,执行一些清除工作

const stop = watchEffect((onInvalidate) => {
        const timer = setTimeout(() => {
          console.log("网络请求成功~");
        }, 2000)

        // 根据name和age两个变量发送网络请求
        onInvalidate(() => {
          // 在这个函数中清除额外的副作用
          // request.cancel()
          clearTimeout(timer);
          console.log("onInvalidate");
        })
        console.log("name:", name.value, "age:", age.value);
});

调整watchEffect的执行时机

  默认值是pre,它会在元素 挂载 或者 更新 之前执行;
  post,将推迟副作用的初始运行,直到组件的首次渲染完成
  sync,这将强制效果始终同步触发。然而,这是低效的,应该很少需要

watchEffect(() => {
      console.log(title.value);
}, {
      flush: "post"
})

Watch

  懒执行副作用(第一次不会直接执行);
  更具体的说明当哪些状态发生变化时,触发侦听器的执行;
  访问侦听状态变化前后的值;

侦听单个数据源

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

const info = reactive({name: "why", age: 18});
// 1.侦听watch时,传入一个getter函数
      watch(() => info.name, (newValue, oldValue) => {
      console.log("newValue:", newValue, "oldValue:", oldValue);
 })

// 2.传入一个可响应式对象: reactive对象/ref对象
// 情况一: reactive对象获取到的newValue和oldValue本身都是reactive对象
watch(info, (newValue, oldValue) => {
      console.log("newValue:", newValue, "oldValue:", oldValue);
})

// 情况二: ref对象获取newValue和oldValue是value值的本身
      const name = ref("why");
      watch(name, (newValue, oldValue) => {
      console.log("newValue:", newValue, "oldValue:", oldValue);
})


 // 如果希望newValue和oldValue是一个普通的对象
watch(() => {
        return {...info}
}, (newValue, oldValue) => {
        console.log("newValue:", newValue, "oldValue:", oldValue);
 })

//上面简便写法
watch(() => ({...info}), (newValue, oldValue) => {
        console.log("newValue:", newValue, "oldValue:", oldValue);
 })

侦听多个数据源

// 1.定义可响应式的对象
 const info = reactive({name: "why", age: 18});
 const name = ref("why");

// 2.侦听器watch
watch([() => ({...info}), name], ([newInfo, newName], [oldInfo, oldName]) => {
        console.log(newInfo, newName, oldInfo, oldName);
})

Watch 参数 

  深层的侦听 设置 deep 为true

  立即执行 设置 immediate 为true

posted @ 2021-12-27 15:11  Hexrui  阅读(61)  评论(0编辑  收藏  举报
返回顶部