【问题标题】:Why does watchEffect trigger while the watched value is not changed?为什么 watchEffect 会在 watched 值没有改变的情况下触发?
【发布时间】:2022-12-07 12:10:48
【问题描述】:

我有一个组件保留 Pinia 存储数据的本地部分副本。

<template>
  <h3>Order idx {{ idx }}: sum = {{ localSum }}, store sum = {{ getOrderSum() }}</h3>
  <input type="number" v-model="localSum" />
  <button @click="updateSum">Save</button>
</template>

<script setup>
import { useCounterStore } from '../store/counter'
import { watchEffect, ref, defineProps, watch } from 'vue'

const props = defineProps({
  idx: 0
})

const store = useCounterStore()

const localSum = ref(0)

function getOrderSum() {
  return store.getOrderIdxSumMap[props.idx]
}

function updateSum() {
  store.setOrderSum(props.idx, localSum.value)
}

watch(
  () => getOrderSum(),
  (newValue) => {
    console.log('i am updated')
    localSum.value = newValue
  }, {
    immediate: true,
  }
)

/*
watchEffect(() => {
  console.log('i am updated')
  localSum.value = getOrderSum()
})
*/
</script>

每当外部数据更改时,本地副本都应更新。使用 watchEffect 而不是 watch 会导致具有已修改和未保存数据的组件丢失用户输入。

watchEffect行为描述1:

  1. 更改一阶数据
  2. 点击保存
  3. 您将在控制台中看到两次i am updated。

    watchEffect行为描述2:

    1. 更改首单数据
    2. 更改二阶数据
    3. 在第一个订单上点击保存
    4. 您会看到第二个订单更改丢失

      注释掉 watchEffect 并取消注释 watch。现在一切正常。是我的误解还是值得报告的错误?

      Full demo

【问题讨论】:

    标签: vue.js vuejs3 pinia


    【解决方案1】:

    是how watch and watchEffectsupposed to work

    简而言之,watch根据其dependencies value跟踪变化。
    watchEffect 根据其 dependencies effect 跟踪更改。

    在您的示例中,watch 和watchEffect 具有相同的依赖项,即store.getOrderIdxSumMap 和props.idx。因此,当您单击保存按钮更新这些依赖项时,流程将是:

    • watch 知道依赖已经改变了。它重新计算源值,然后将 oldValue 与 newValue 进行比较。如果oldValue !== newValue,就会触发回调
    • watchEffect 知道依赖已经改变了。它不关心值,只是触发回调

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      相关资源
      最近更新 更多