7

我正在更新发送到 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 上的项目

还有现场演示

帮助表示赞赏

4

2 回答 2

4

该组件没有更新,因为您的嵌套值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

于 2019-09-19T12:07:46.690 回答
1

如果需要,您可以在发出后在父组件中调用 this.$forceUpdate() ,这将强制重新渲染。

不确定为什么您的子组件没有自动触发更新的根本问题。

于 2019-09-19T00:37:17.727 回答