Vue子组件不会在道具更改时更新

时间:2019-09-18 20:06:07

标签: javascript vue.js data-binding components vue-props

我正在更新一个“运动”道具,该道具将被发送到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)"
>

Here's the project on Github

And a live demo

帮助赞赏?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

该组件未更新,因为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