VueJs 组件的 Prop 相关计算属性对对象数组 Prop 更改没有反应

Posted

技术标签:

【中文标题】VueJs 组件的 Prop 相关计算属性对对象数组 Prop 更改没有反应【英文标题】:VueJs Component's Prop-Dependent Computed Property Not Reactive to Array of Objects Prop Changes 【发布时间】: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

【问题讨论】:

您尝试使用@watch,it 可能有帮助吗? 如何在父节点上设置数组问题的新值? 如何更改父母提出的道具问题?某些更改可能不是被动的 @yuri @Oliver :questions="questionsInParent", questionsInParent 设置如下:&lt;another-component @questionsArrived="Object.assign(questionsInParent, $event)&gt;...&lt;/another-component&gt; 【参考方案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)"时不会。

以上是关于VueJs 组件的 Prop 相关计算属性对对象数组 Prop 更改没有反应的主要内容,如果未能解决你的问题,请参考以下文章

计算嵌套属性 Vuejs

vueJs-非prop的特性

如何将计算属性中的 vuex 数据传递给 data prop

VueJS - 函数的结果作为 Prop 的默认值

Vuejs 父子组件通信

在 VueJS 中使用计算属性搜索过滤器