【问题标题】:VueJs Component's Prop-Dependent Computed Property Not Reactive to Array of Objects Prop ChangesVueJs 组件的 Prop 相关计算属性对对象数组 Prop 更改没有反应
【发布时间】:2020-11-12 18:53:49
【问题描述】:

背景

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

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

还有两个按钮,点击时分别调用previousQuestion()nextQuestion()

问题

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

但是,即使在 prop questions 更改之后,计算的 question 也不会重新计算。

另一方面,当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 开发工具屏幕

Computed question still sits at its default state

【问题讨论】:

  • 您尝试使用@watchit 可能有帮助吗?
  • 如何在父节点上设置数组问题的新值?
  • 如何更改父母提出的道具问题?某些更改可能不是被动的
  • @yuri @Oliver :questions="questionsInParent", questionsInParent 设置如下:&lt;another-component @questionsArrived="Object.assign(questionsInParent, $event)&gt;...&lt;/another-component&gt;

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


【解决方案1】:

您总是可以添加一个观察者并解决它,但问题在于 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

最后:

How to clone objects on javascript

【讨论】:

  • 我尝试在我的子组件中观看 questions 道具,但尽管从 devtools 中看到 questions 道具确实发生了变化,但 Vue 没有检测到变化。
  • 我最初使用Object.assign实际上会导致道具发生变化,但使用@questionsArrived="questions = Object.assign({}, questions, $event)"时不会。
猜你喜欢
  • 2017-11-18
  • 1970-01-01
  • 2017-11-09
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
相关资源
最近更新 更多