vue3笔记:侦听器

watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组。

watch()

侦听一个ref、计算属性、getter 函数
watch(ref变量, (newValue, oldValue) => {})。当ref值发生变化时会触发相应的回调(回调中可进行异步操作)。

<script>
import { ref, watch } from "vue";
const count = ref<number>(0);
const double = computed(() => count.value * 2);
const obj = reactive({
    count: 0,
});
// 1. 可以单个侦听
watch(count, async (newVal, oldVal) => {
  try {
    const res = await fetch('https://yesno.wtf/api')
    console.log("res...", res);
  } catch (error) {
    console.log("error...", error);
  }
});
watch(double, async (newVal, oldVal) => {
  console.log("double变化了...", newVal, oldVal);
});
watch(() => obj.count, async (newVal, oldVal) => {
  console.log("obj.count变化了...", newVal, oldVal);
});

// 2. 可以写在一个watch里,然后通过判断对应下标的新旧值变化分别执行不同操作
watch([count, double, () => obj.count], async (newVal, oldVal) => {
  // 判断count变化
  if (newVal[0] !== oldVal[0]) {
    console.log("count变化了...");
  }
  // 判断double是否变化
  if (newVal[1] !== oldVal[1]) {
    console.log("double变化了...");
  }
  // 判断obj.count变化了
  if (newVal[2] !== oldVal[2]) {
    console.log("obj.count变化了...", newVal[2], oldVal[2]);
  }
});

// 3. 或者写在一个watch里,然后通过解构的方法拿到对应的新旧值
watch(
  [count, double, () => obj.count],
  ([newCount, newDouble, newObjCount], [oldCount, oldDouble, oldObjCount]) => {
    console.log(newCount, newDouble, newObjCount);
    console.log(oldCount, oldDouble, oldObjCount);
  }
);
</script>

侦听一个reactive

1、 默认隐式创建一个深层侦听器

直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发:

<script>
import { reactive, watch } from "vue";
const obj = reactive({
  count: 10,
  someObject: {
    count: 20,
  },
});
const increceCount = function () {
  // obj底下任何key值被修改都会触发watch
  obj.someObject.count++;
};
watch(
  obj,
  (newValue, oldValue) => {
    console.log("obj变化了...", newValue, oldValue);
  }
);
</script>

一个返回响应式对象的 getter 函数,只有在返回不同的对象时,才会触发回调:

<script>
import { reactive, watch } from "vue";
const obj = reactive({
  count: 10,
  someObject: {
    count: 20,
  },
});
const increceCount = function () {
  // 1. 只有当obj.someObject被替换时才会触发watch
  obj.someObject = { ...obj.someObject };
  // 2. 像这种直接修改某个key值的不会触发watch
  obj.someObject.count++;
};
watch(
  () => obj.someObject,
  (newValue, oldValue) => {
    console.log("obj变化了...", newValue, oldValue);
  }
);
</script>

2、 显性创建一个深层侦听器

传入第三个参数加上 deep 选项,强制转成深层侦听器:

<script>
import { reactive, watch } from "vue";
const obj = reactive({
  count: 10,
  someObject: {
    count: 20,
  },
});
const increceCount = function () {
  // 直接修改某个key值的会触发watch
  obj.someObject.count++;
};
watch(
  () => obj.someObject,
  (newValue, oldValue) => {
    console.log("obj变化了...", newValue, oldValue);
  },
  {
    deep: true,
    // immediate 为 true 立即执行,且当 obj.someObject 改变时再次执行
    immediate: true,
  }
);
</script>

注意:当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

watchEffect()

回调函数里面执行一些异步操作(副作用逻辑)时,可以省略第一个参数,第一个 await 使用过程及其之前用到的所有响应式变量发生变化都会被触发。

const count = ref<number>(0);
const name = ref<string>("");
const age = ref<number>(10);
const obj = reactive({
  count: 10,
  someObject: {
    count: 20,
  },
});
const increceCount = function () {
  count.value++;
  // 只改变obj深层的变量,await及其之前没有使用到someObject的内容,watchEffect回调不会被触发(浅层监听)
  // 包括直接使用obj,obj.someObject,使用obj.someObject.count则可以监听到
  obj.someObject.count++;
};
watchEffect(async () => {
  // count name obj.count 变化都会触发watchEffect回调
  console.log(count.value); 
  const res = await fetch(
    `https://yesno.wtf/api?count=${obj.count}&name=${name.value}`
  );
  // age变化不会触发回调
  age.value++;
  console.log("watchEffect res1...", res, age.value);
});

watchPostEffect() 和 watchSyncEffect()

watch 的第三个参数,以及 watchEffect 的第二个参数里面都可以添加相应的配置实现 watchPostEffect()watchSyncEffect(),也可以说 watchPostEffect()watchSyncEffect()watchwatchEffect 添加不同参数之后的简写。

1、 watchPostEffect()

相当于传入 flush: 'post',可以在 watchwatchEffect 回调中获取到更新之后的 dom,也就是回调会在 dom 更新之后执行(默认在 dom 更新之前执行,也就是 flush: 'pre'参数说明传送门)。

watch(source, callback, {
  flush: 'post'
})

watchEffect(callback, {
  flush: 'post'
})

2、 watchSyncEffect()

使用 flush: 'sync' 选项时的别名,在响应式依赖发生改变时立即触发侦听器(谨慎使用,如果有多个属性同时更新,将导致一些性能和数据一致性的问题)。

watch(source, callback, {
  flush: 'sync'
})

watchEffect(callback, {
  flush: 'sync'
})

侦听器传送门

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值