Vue 计算属性不会在更新其反应性依赖项时更新

Posted

技术标签:

【中文标题】Vue 计算属性不会在更新其反应性依赖项时更新【英文标题】:Vue computed property not updating on update of their reactive dependency 【发布时间】:2021-09-06 21:24:08 【问题描述】:

我不熟悉在 Vue 计算属性中使用 get 和 set 方法。我在计算中有以下代码。

editSmallText: 
      get() 
        return this.word.translation.smallText.join("");
      ,
      set(value) 
        if (typeof value == "string") this.editSmallTextArray = value.split("");
        else this.editSmallTextArray = value;
      ,
    ,

我使用 this.editSmallText 作为输入的 v-model。我将 this.word 作为组件道具中的对象,并将 this.editSmallTextArray 作为数据中的数组。现在,如果我在输入字段中更改某些内容 this.editSmallTextArray 得到更新,我将更新的值分配给函数内的 this.word.translation.smallText 并将 this.word.translation.smallText 的更新值发送到 firebase 的更新函数,该函数在 firebase 中更新它火库。并将模板中的更新值设为 word.translation.smallText ,但在我的输入 v-model 中,我仍然在 editSmallText v-model 中获得 this.word.translation.smallText 的旧值,直到我刷新页面/重新加载组件。我不确定为什么 editSmallText 在 word.translation.smallText 更新时没有得到更新。

<p class="text-h5 q-mb-sm text-center" v-if="!editSmall">
               word.translation.smallText.join("") 
            </p>
            <q-input
              v-model="editSmallText"
              class="text-white"
              dense
              standout
              dark
              v-else
              autogrow
              sanitize
            />

<q-btn
              icon="edit"
              @click="editSmall = !editSmall"
              size="sm"
              round
              flat
              dense
              class="text-white"
              v-if="!editSmall"
            />

            
            <q-btn
              icon="save"
              class="text-white"
              @click="saveEditSmallText()"
              size="sm"
              v-if="editSmall"
              round
              flat
              dense
            />

props: word: Object, isSelected: Boolean ,

data()
return 
      editSmall: false,
      editSmallTextArray: [],
      

computed:
editSmallText: 
      get() 
        return this.word.translation.smallText.join("");
      ,
      set(value) 
        if (typeof value == "string")
          this.editSmallTextArray = value.split(",");
        else this.editSmallTextArray = value;
      ,
    ,
,
methods:
saveEditSmallText() 
      this.editSmall = !this.editSmall;
      this.word.translation.smallText = this.editSmallTextArray;
      this.edit();
    ,
edit() 
      let payload = 
        word: this.word.word,
        id: this.$el.id,
        updatedAt: new Date(),
        smallText: this.word.translation.smallText,
        dictionary: this.word.translation.orgTrans.dictionary,
        transcription: this.word.translation.orgTrans.transcription,
      ;
      this.$store.dispatch("updateWord", payload);
      this.$q.notify(
        color: "positive",
        textColor: "white",
        icon: "update",
        position: "top",
        message: this.$t("Changes saved successfully!"),
        timeout: 3000,
      );
    ,

【问题讨论】:

您需要添加更多代码...或者更好的是,创建一个Minimal, Reproducible Example @MichalLevý 现在请看一下我添加了更多代码,包括数据和方法。看看能不能帮上忙。谢谢 【参考方案1】:

它不更新的原因是它们是两个独立的对象引用。您的 v-model 通过来自 prop 的 get() 方法获取其值,同时更新保存到 set() 方法中的 data 属性。

如果你坚持使用 prop 来保存值,你的组件应该 $emitset() 方法中对该值的任何更改,并让父组件执行实际更新。

或者,当组件为 mounted() 时,您可以将 prop 克隆到您的 data,从而无需计算。如果父组件中 prop 的值发生变化,则需要 watch 并相应地更新 data

【讨论】:

感谢 $emit() 对父组件的更改解决了问题【参考方案2】:

单词 prop 是响应式的,但单词 prop 的翻译属性不是响应式的。

翻译属性很可能是后来添加的

将翻译属性添加到单词对象不会触发更新的钩子。

尝试定义一个默认值

props: 
  word: 
     type:Object,
     required: false,
     default: 
         translation: null
     
  ,

【讨论】:

【参考方案3】:

我在尝试更新子组件内的this.word.translation.smallText 时犯了一个错误,因为它是一个道具,应该通过实际组件(即父组件)中的 $emit 进行更新。一旦我更新了 this.word.translation.smallText 在其实际组件中的值,我的问题就解决了。

【讨论】:

以上是关于Vue 计算属性不会在更新其反应性依赖项时更新的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js计算属性在通过事件时失去其反应性

如何更新反应性对象(和一般属性)?

Vue计算属性

Vue.js 3 - 替换/更新反应性对象而不会失去反应性

vue.js 是不是更新依赖于方法的计算属性?

vue.js 不会在mounted() 挂钩上更新