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

时间:2021-06-23 10:14:10

标签: javascript vue.js vue-component computed-properties vue-reactivity

我是在 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,
      });
    },
}

3 个答案:

答案 0 :(得分:1)

prop 是反应性的,但是 prop 的翻译属性不是反应性的。

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

enter image description here

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

尝试定义一个默认值

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

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

相关问题