Как избежать неожиданного побочного эффекта в вычисляемых свойствах - VueJS - PullRequest
1 голос
/ 20 марта 2020

Я пытаюсь предварительно заполнить форму данными из хранилища vuex. В предоставленном коде есть ожидаемый результат, мне нужно, но я знаю, что это не способ сделать это. Я довольно новичок в Vue / Vuex. Входные данные используют v-модель, поэтому я не могу использовать :value="formInformation.parentGroup" для предварительного заполнения.

  data() {
    return {
      groupName: { text: '', state: null },
      parentName: { text: '', state: null },
    };
  },
  computed: {
    formInformation() {
      const groups = this.$store.getters.groups;
      const activeForm = this.$store.getters.activeForm;
      if (activeForm.groupIndex) {
        const formInfo = groups[0][activeForm.groupIndex][activeForm.formIndex]
        this.groupName.text = formInfo.name // Is there a way to not use this unexpected side effect ?
        return formInfo;
      } else {
        return 'No Form Selected';
      }
    },
  },

Я так долго искал ответ, что мне просто нужно было его спросить. Может быть, я просто ищу что-то не так, но, может быть, кто-то здесь может мне помочь.

Ответы [ 3 ]

1 голос
/ 20 марта 2020

С вами все в порядке, требуется лишь небольшой рефакторинг и разделение - разделите все логи c на вычисляемые свойства (вы также можете использовать mapGetters):

  mounted() {
    if (this.formInformation) {
      this.$set(this.groupName.text, this.formInformation.name);
    }
  },
  computed: {
    groups() {
      return this.$store.getters.groups;
    },
    activeForm() {
      return this.$store.getters.activeForm;
    },
    formInformation() {
      if (this.activeForm.groupIndex) {
        return this.groups[0][this.activeForm.groupIndex][
          this.activeForm.formIndex
        ];
      }
    }
  }
0 голосов
/ 20 марта 2020

Избегайте мутаций data property в computed.

Computed предназначены для выполнения какой-либо операции (например, reduce, filter et c) над data Свойства & просто return result.

Вместо этого вы можете попробовать это:

computed: {
  formInformation() {
    const groups = this.$store.getters.groups;
    const activeForm = this.$store.getters.activeForm;
    if (activeForm.groupIndex) {
      const formInfo = groups[0][activeForm.groupIndex][activeForm.formIndex]
      // this.groupName.text = formInfo.name // <-- [1] simply, remove this
      return formInfo;
    } else {
      return 'No Form Selected';
    }
  }
},

// [2] add this, so on change `formInformation` the handler will get called
watch: {
 formInformation: {
  handler (old_value, new_value) {
   if (new_value !== 'No Form Selected') { // [3] to check if some form is selected 
    this.groupName.text = new_value.name // [4] update the data property with the form info
   },
   deep: true, // [5] in case your object is deeply nested
  }
 }
}
0 голосов
/ 20 марта 2020

Вы можете сделать groupName вычисляемым свойством:

computed: {
    groupName() {
         let groupName = { text: '', state: null };
         if (formInformation.name) {
          return groupName.text = formInfo.name;
         }
         return groupName;
    }

Или вы можете установить наблюдателя на formInformation:

watch: {
    formInformation: function (newFormInformation, oldFormInformation) {
      this.groupName.text = formInfo.name;
    }
  },
...