0

背景

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

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

还有两个按钮可以调用previousQuestion()nextQuestion()单击时。

问题

根据 Vue.js devtools,propquestions确实绑定并响应来自父级的更改。

但是,即使在 prop更改后,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 开发工具屏幕

Computedquestion仍处于默认状态

4

1 回答 1

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 如何生成副本:

Object.assign - MDN Javascript

最后:

如何在 javascript 上克隆对象

于 2020-07-23T22:02:31.220 回答