VueJs组件的依赖于属性的计算属性对对象数组的属性更改无反应

时间:2020-07-23 05:43:24

标签: vuejs2 vue-component vue-reactivity vue-props

背景

我有一个Vue组件question-panel,它接受​​一个道具questions,道具是一个对象数组,并且长度可变。

<template>...</template>中,有一些HTML元素可显示计算的question对象的信息,例如question.namequestion.score等。

还有两个按钮,它们在单击时分别调用previousQuestion()nextQuestion()

问题

根据Vue.js devtools,道具questions确实对父项的更改进行绑定并做出反应。

但是,即使更改了属性question,也不会重新计算计算出的questions

另一方面,当questionIndex更改时,它的确会重新计算。

我应该如何解决此问题?这种实施违反Vue的原则吗?

QuestionPanel.vue的片段

<script>
export default {
  props: {
    questions: Array,
  },

  data() {
    return {
      questionIndex: 0,
    };
  },

  computed: {
    question: function () {
      return this.questions[this.questionIndex];
    },
  },

  methods: {
    previousQuestion() {
      if (this.questionIndex > 0) {
        this.questionIndex--;
        this.$emit("questionChanged", this.question);
      }
    },
    nextQuestion() {
      if (this.questionIndex < this.questions.length - 1) {
        this.questionIndex++;
        this.$emit("questionChanged", this.question);
      }
    },
  },
};
</script>

Parent.Vue段

<paper-panel
  @questionsArrived="Object.assign(questions, $event)"
></paper-panel>

<question-panel
  :questions="questions"
></question-panel>

Vue.js Devtools屏幕

Computed question still sits at its default state

1 个答案:

答案 0 :(得分:0)

您总是可以添加观察者并解决它,但是问题在于question道具的反应性。

Object.assign未执行阵列的深层复制,建议您尝试以下操作:

Object.assign({}, questionsInParent, $event)

代替

Object.assign(questionsInParent, $event)

为什么?因为Object.assign会做键和值的浅表副本。 您的道具是一个对象数组,因此在执行Object.assign时,您仅应对数组中每个对象的引用,因此它实际上未检测到任何更改,因为引用可能仍然相同。


该主题涵盖于:

https://vuejs.org/v2/guide/reactivity.html#For-Objects

您还可以查看对象分配如何产生副本:

Object.assign - MDN Javascript

最后:

How to clone objects on javascript