Дочерний компонент Vue не обновляется при изменении проп - PullRequest
0 голосов
/ 18 сентября 2019

Я обновляю реквизит для упражнений, который отправляется компоненту тренировки в Vue.В дочернем компоненте я запускаю функцию для увеличения набора, который вы используете.Функция запускается в родительском компоненте (я получаю console.logs ()), но дочерний компонент не выполняет повторную визуализацию.

Родитель:

<ExerciseListItem
  v-for="(exercise) in exercises"
  v-on:completeSet="completeSet"
  v-on:selectExercise="selectExercise"
  v-bind:exercise.sync="exercise"
  v-bind:isActiveExercise="exercise.slug === activeExerciseSlug"
  v-bind:key="exercise.slug"
/>

методы:

methods: {
  completeSet: function(slug) {
    console.log("complete-set", slug);
    const exercise = this.getExerciseBySlug(slug);
    exercise.completedSets++;
    if (exercise.completedSets === exercise.totalSets) {
      this.completeExercise(slug);
    }
  },
  completeExercise: function(slug) {
    this.getExerciseBySlug(slug).isComplete = true;
    console.log("COMPLETE-exercise", slug);
  },
  getExerciseBySlug: function(slug) {
    return this.exercises.find(exercise => exercise.slug === slug);
  },
  selectExercise: function(selectedSlug) {
    this.activeExerciseSlug = selectedSlug;
  }
},

Дочерний шаблон

<li
  v-bind:class="{ 'white-box': true, complete: exercise.isComplete }"
  v-on:click="exercise.totalSets > 1 ? $emit('selectExercise', exercise.slug) : $emit('completeSet', exercise.slug)"
>

Вот проект на Github

И живая демонстрация

Помощь оценена ?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2019

Компонент не обновляется, потому что вложенные значения вашего prop не являются реактивными, следовательно, vue не замечает, что они изменяются.

Как сделать вложенные свойства реактивными в Vue

Следующее относится ко всем состояниям в вашем приложении vue - независимо от того, находится ли оно в хранилище vuex, в параметре data() или внутри prop.

По умолчанию vue делает состояние реактивным толькоесли это объявлено.Это означает, что динамически (во время выполнения) назначенное состояние не является реактивным (например, mounted() { this.bar = 'two' } не создаст реактивное свойство bar в вашем data()).

Если вы хотите динамически создать реактивное состояние, есть дваправила, которым вы должны следовать:

  1. Все свойства должны быть установлены с помощью Vue.set(rootObject, key, value) (например, mounted() { this.$set(this, 'bar', 'two') } - this.$set() - это псевдоним для Vue.set()).Прочитайте об этом здесь: Vue Doku

  2. Массивы должны быть заполнены собственными свойствами массива (Array.prototype.push() и т. Д.).Установка элементов массива по индексу не сделает эти элементы реактивными. Примечание: Vue.set(rootArray, 1, value) также не будет работать - так как он устанавливает элемент по индексу.Подробнее об этом здесь: Vue Gotchas

0 голосов
/ 19 сентября 2019

При необходимости вы можете вызвать это. $ ForceUpdate () в родительском компоненте после emit, что вызовет повторную визуализацию.

Не уверен, что основная проблема заключается в том, почему ваш дочерний компонент не запускаетобновлять автоматически.

...