文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue3下的watch怎么使用

2023-05-17 13:14

关注

对于WatchOptions的参数配置:

deep:当需要对对象等引用类型数据进行深度监听时,设置deep: true,默认值是false。
immediate:默认情况下watch是惰性的,设置immediate: true时,watch会在初始化时立即执行回调函数一次。
flush:控制回调函数的执行时机,。它可设置为 pre、post 或 sync。
pre:默认值,当监听的值发生变更时,优先执行回调函数(在dom更新之前执行)。
post:dom更新渲染完毕后,执行回调函数。
sync:一旦监听的值发生了变化,同步执行回调函数(建议少用)。

一,监听单个数据ref

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

可以获取到新值和旧值。

二,监听引用类型数据ref:深度监听

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

即使整个数组作为引用数据类型被监听,它内部的某一项发生变更也不会被观察到。所以watch中的代码并没有执行。

1,引用类型ref直接深度监听

此时,就需要使用深度监听: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 }
);

值发生了变更 Proxy {a: 5, b: 2} Proxy {a: 5, b: 2}

可以注意到的是,深度监听的需要是这个引用数据类型自身,而不是其中的属性。并且,他只能获取到新值,而获取不到旧的值。

2,引用类型ref深拷贝深度监听

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 }
);

这样把watch的引用类型数据源深拷贝一份,即可完成对新旧值得获取:

值发生了变更 {a: 5, b: 2} {a: 1, b: 2}

三,监听单个数据:reactive

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

这里主要是() => single.count,监听的是single中的count,只有这个属性发生了变化才会触发回调函数。这种情况下是可以获取到新旧值的。

四,监听引用类型数据: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 'vue';
const single = reactive({ count: 1, test: { a: 1, b: 2 } });
const handleClick = function () {
  single.test.a++;
};
watch(
  single,
  (newValue, oldValue) => {
    console.log('值发生了变更', newValue, oldValue);
  },
  { immediate: true }
);
</script>

reactive的数据,用不用deep:true是没有影响的,single中的一个属性发生了变化,都能被监听到,继而执行回调函数。

和三中有所不同的是,这种情况下是只能获取到新值的。

五,immediate: true

默认情况下watch是惰性的,当我们设置immediate: true时,watch会在初始化时立即执行回调函数

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

六,监听多个数据源

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

如果两个值同时发生变更,则会仅触发一次watch的回调函数,而对于每个值的变更都会引发watch的回调函数。

如果想变更一格数据就触发一次回调,可以在两个数据变更中间加下nextTick。

七,flush的配置

1,默认情况下在dom渲染完毕前调用回调函数

回调函数优先于DOM更新执行,监听值变更时,flush默认为pre。这就意味着,如果在回调函数中有相关dom的操作,而参数里面配置了immediate:true,则会报错,因为这个时候dom还没有被渲染,是获取不到dom的。

接下来看下代码:

<template>
  <div class="mine-box">
    <div ref="countDom">{{ count }}</div>
    <button @click="handleClick">按钮</button>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';
const count = ref(1);
const countDom = ref(null);
const handleClick = function () {
  count.value++;
};
watch(
  count,
  (newValue, oldValue) => {
    console.log('---', countDom.value.textContent);
    console.log('值发生了变更', newValue, oldValue);
  },
  { deep: true }
);
</script>

得到的结果:

--- 1值发生了变更 2 1

在回调函数中,新的值已经变成了2,但获取到的DOM仍然是之前的。默认情况下,flush的值为pre。当值发生变化时,回调函数将在DOM更新之前被触发执行。

2,flush: 'post&rsquo;在dom渲染完毕后执行回调函数

<template>
  <div class="mine-box">
    <div ref="countDom">{{ count }}</div>
    <button @click="handleClick">按钮</button>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';
const count = ref(1);
const countDom = ref(null);
const handleClick = function () {
  count.value++;
};
watch(
  count,
  (newValue, oldValue) => {
    console.log('---', countDom.value.textContent);
    console.log('值发生了变更', newValue, oldValue);
  },
  { deep: true, flush: 'post' }
);
</script>

得到的结果:

--- 2值发生了变更 2 1

当回调函数被调用时,DOM已经更新完成,此时获取到的DOM是经过数据更改后更新完成的DOM。

以上就是vue3下的watch怎么使用的详细内容,更多请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯