最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue computed property not updating on update of their reactive dependency - Stack Overflow

programmeradmin1浏览0评论

I am new to using get and set methods in Vue puted property. I have the following code in puted.

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

I am using this.editSmallText as v-model for input. And I have this.word as object in props of ponents and this.editSmallTextArray as array in the data. Now if I change something in input feild this.editSmallTextArray gets updated and I assign that updated value to this.word.translation.smallText inside a function and send this.word.translation.smallText's updated value to firebase's update function which update it in firebase firestore. And get the upated value in template as {{ word.translation.smallText }} but in my input v-model I still get the old value of this.word.translation.smallText in editSmallText v-model untill I refresh the page/reload ponent. I'm not sure why editSmallText is not getting updating on update of 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: [],
      }
}
puted:{
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.translationTrans.dictionary,
        transcription: this.word.translationTrans.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,
      });
    },
}

I am new to using get and set methods in Vue puted property. I have the following code in puted.

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

I am using this.editSmallText as v-model for input. And I have this.word as object in props of ponents and this.editSmallTextArray as array in the data. Now if I change something in input feild this.editSmallTextArray gets updated and I assign that updated value to this.word.translation.smallText inside a function and send this.word.translation.smallText's updated value to firebase's update function which update it in firebase firestore. And get the upated value in template as {{ word.translation.smallText }} but in my input v-model I still get the old value of this.word.translation.smallText in editSmallText v-model untill I refresh the page/reload ponent. I'm not sure why editSmallText is not getting updating on update of 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: [],
      }
}
puted:{
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.translationTrans.dictionary,
        transcription: this.word.translationTrans.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,
      });
    },
}
Share Improve this question edited Jun 23, 2021 at 14:24 Zulqarnain Haider asked Jun 23, 2021 at 10:14 Zulqarnain HaiderZulqarnain Haider 793 silver badges13 bronze badges 2
  • You need to add more code ...or better yet, create a Minimal, Reproducible Example – Michal Levý Commented Jun 23, 2021 at 10:20
  • @MichalLevý kindly take a look now I have added more code including data and methods. See if it can help. Thanks – Zulqarnain Haider Commented Jun 23, 2021 at 14:27
Add a ment  | 

3 Answers 3

Reset to default 2

The reason it's not updating is they are two separate object references. Your v-model gets its value via the get() method from a prop, while updates are being saved to a data property in the set() method.

If you insist on using a prop to hold the value, your ponent should $emit any changes to that value in the set() method and let the parent ponent perform the actual update.

Alternatively you can clone the prop to your data when the ponent is mounted(), removing the need for a puted. If the prop's value changes in the parent ponent, you will need to watch and update the data accordingly.

the word prop is reactive, but the translation property of the word prop is not reactive.

The translation property was most likely added afterwards

adding the translation property to word object does not trigger updated hook.

try to define a default value

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

I was making a mistake by trying to update the this.word.translation.smallText inside the child ponent as it is a prop and should be updated via $emit in the actual ponent i.e parent ponent. My problem was solved once I updated the value of this.word.translation.smallText in its actual ponent from where I was getting it as a prop.

发布评论

评论列表(0)

  1. 暂无评论