Что влияет на повторное вычисление Vue вычисляемого свойства? - PullRequest
0 голосов
/ 07 августа 2020

Я ожидаю, что currentSelectionViewContent будет пересчитываться каждый раз при изменении selectedOptionsIndexes. Действительно, иногда работает, иногда - нет.

import { Component, Prop, Vue, Watch } from "vue-property-decorator";

@Component({
  template
})
export class SelectField extends Vue {

  private onNewOptionSelected(newOption: SelectField.Option, indexInArray: number): void {

    console.log("~~~~~~~~~~~~~~~");
    console.log(JSON.stringify(this.selectedOptionsIndexes, null, 2));

    this.selectedOptionsIndexes[0] = indexInArray;

    console.log(JSON.stringify(this.selectedOptionsIndexes, null, 2));
    console.log("--------------");

    if (isUndefined(newOption.key)) {
      this.$emit("change", newOption.relatedEntity);
    } else {
      this.$emit("change", newOption.key);
    }
  }

  // Vue computed property in "vue-property-decorator" syntax
  private get currentSelectionViewContent(): string {
    console.log("Recomputing ...");
    switch (this.selectedOptionsIndexes.length) {
      case 0:
        return SelectField.DEFAULT_NOTHING_SELECTED_PLACEHOLDER;
      case 1:
        return this.selectOptions[this.selectedOptionsIndexes[0]].title;
      default:
        return SelectField.DEFAULT_MULTIPLE_OPTIONS_SELECTED_LETTERING;
    }
  }
}

Рабочий случай:

enter image description here

Not working case (no re-computing):

введите описание изображения здесь

К сожалению, не было создано репро для этого случая (воспроизведение компонента, вызывающего эту проблему, его зависимостей, а также среды), занимает слишком много времени. Если вы не можете понять, что здесь не так, без воспроизведения, пожалуйста, просто научите меня, что влияет на волю Vue вычисленное свойство повторно вычислено или нет.

1 Ответ

1 голос
/ 07 августа 2020

Vue имеет определенное поведение вокруг массивов, о котором нужно знать. Из документы :

Vue не могут обнаружить следующие изменения в массиве:

  • Когда вы напрямую устанавливаете элемент с индексом, например, vm.items [indexOfItem] = newValue
  • Когда вы изменяете длину массива, например, vm.items.length = newLength

Чтобы Vue видел изменение вашего массива, всегда делайте копию массива и переназначайте ее, например:

var updatedIndexes = [...this.selectedOptionsIndexes]; // Copies array
updatedIndexes[0] = indexInArray; // Update the copy
this.selectedOptionsIndexes = updatedIndexes; // Overwrite with copy
...