0
点赞
收藏
分享

微信扫一扫

记录一个前端下载zip文件无法打开的问题

Java架构领域 03-07 20:00 阅读 2

问题
当我给响应式变量赋相同值时watch不会被触发。

之前一直对于watch的理解是会被频繁触发,值变化就会被执行,反之computed会缓存相同值。
看官方文档也没有相关说明,加上赋相同值的场景占少数

结论
在 Vue 3 中,watch 函数默认情况下只在被观察的响应式值发生更改时触发。
如果你为一个响应式变量赋予了相同的值(即赋值前后没有变化),那么watch不会触发。
例如,假设你有以下代码:

import { ref, watch } from 'vue';

export default {
  setup() {
    const myVar = ref(false);

    watch(myVar, (newValue, oldValue) => {
      console.log('myVar changed from', oldValue, 'to', newValue);
    });

    // 设置一些延迟然后为myVar赋相同的值
    setTimeout(() => {
      myVar.value = false;
    }, 2000);

    return {};
  },
};

上面的代码中,尽管你在2秒后为myVar重新赋值了false,但watch中的回调函数并不会执行,因为其值并没有真正的变化。
如果需要即使赋予相同的值时也触发watch,你可以使用watch的deep和flush选项,但这在上述情况下并不适用。
如果你真的需要在每次赋值时都触发某个函数,不论值是否发生了变化,那你可能需要使用其他的方法,比如自己包装一个函数来进行赋值和触发你需要的操作。

相关疑问
那之前的机制就是不触发还是vue3中被更改了?
Vue 的观察者系统的核心是响应性。Vue 的设计目标之一是避免不必要的计算和渲染,所以当值没有真正变化时,触发 watcher 没有意义,并可能导致不必要的计算或其他效果。

在 Vue 2.x 中,当一个 reactive property 被重新赋予相同的值时,watcher 也是不会被触发的。Vue 3 在这方面的行为并没有改变。

如果你确实需要触发 watcher,即使赋予了相同的值,可以考虑一些变通的方法,例如为该 property 添加一个时间戳或其他的改变值,确保每次赋值都与之前的值不同。但这种方法并不推荐,因为它破坏了数据的语义。

总之,Vue 的这种设计选择是为了性能和避免不必要的渲染。如果在实际应用中遇到问题,建议从业务逻辑的角度考虑如何优化,而不是试图改变 Vue 的默认行为。

这种情况watch和computed有什么区别?
watch 和 computed 在 Vue 中都是观察响应性数据变化的工具,但它们有一些关键的区别:

目的:

computed: 用于声明式地描述一个值如何依赖其他值。它的目标是基于其他响应性属性计算一个值。
watch: 用于执行任何副作用(如调用 API、控制 I/O 或执行其他不纯的操作)当依赖的值发生变化时。
返回值:

computed: 必须返回一个值,并且这个值会被缓存,直到依赖的响应性属性发生变化时才会重新计算。
watch: 没有返回值,它的目的是为了执行一些操作。
响应性:

computed: 自动追踪其内部所依赖的响应性属性。如果这些属性中的任何一个发生变化,计算属性会自动重新计算。
watch: 显式地指定要观察的属性。当这些属性发生变化时,它会执行提供的回调函数。
优化:

computed: 当其依赖的属性未发生变化时,返回值会被缓存,避免不必要的重新计算。
watch: 不会缓存结果,每次属性变化都会执行回调。
使用场景:

computed: 当你需要基于其他属性来派生新的数据时,例如:合计一个列表的总价。
watch: 当你需要在某个属性发生变化时执行异步操作或更复杂的操作,例如:根据用户的输入来查询数据。
在大多数情况下,如果你只是想基于其他属性计算一个新的值,使用 computed 会更合适。但如果你需要在数据变化时执行更复杂的操作或有副作用,那么 watch 会是更好的选择。

也就是computed如果属性变化但是计算结果相同就不会被触发,反之watch会被触发吗?
不完全是

computed:

如果其依赖的属性变化了,但计算结果仍然与上一次相同,那么依赖于这个计算属性的其他响应性系统(例如模板或其他计算属性)不会重新计算或渲染。
总结:计算属性值相同不会触发重新渲染。
watch:

如果你正在观察的响应性属性的值改变了,无论新值是否与旧值相同,watch 的回调都会被触发。但如果属性被设置为与其当前值相同,那么 watch 的回调不会被触发。
总结:属性值相同不会触发 watch 回调。
所以 computed 如果属性变化但是计算结果相同就不会被触发是正确的,但对于 watch 并不完全正确。watch 仅在观察的属性值真正改变时触发,如果重新设置的值与当前值相同,则不会触发。

举报

相关推荐

0 条评论