数组在修改元素时没有反应,仅在添加或删除时

问题描述

我正在使用Vue组件和Laravel编写出版物。

我有一个父组件,称为Publications.vue,其中有2个子组件,分别称为create.vue和list.vue,还有list.vue,我还有一个子组件,分别称为remove.vue和update.vue。

问题是,当我在数组中添加删除发布时,它可以正常运行,但是当我修改元素时,它不起作用。控制器工作正常,但是除非刷新,否则屏幕上什么也没有。

这是我的代码

<template>
    <div class="main">
        <create
            :user="user"
            v-if="showCreate"
            @create="addPublicationOnClient"
        />
  
        <list 
            v-for="(publication,index) in publications"
            :key="publication.id" :publication="publication" :user="user" 
            @deleted="deletePublicationOnClient(index)" 
            @updated="updatePublicationOnClient(index,...arguments)"
        />
    </div>
</template>
addPublication(publication) {
    this.publications.unshift(publication); // works perfect
},deletePublication(index) {
    this.publications.splice(index,1); // works perfect
},updatePublication(index,editedPublication) {
     console.log(editedPublication); // shows the correct value of the edited publication
     
     Vue.set(this.publications,index,editedPublication); // do not react. do not show anything
     this.publications.splice(index,1,editedPublication) // do not react neither. do not show anything
     
     console.log(this.publications); // shows the correct values in the array
}

我将非常感谢您的帮助,因为我确实坚持不懈,并且阅读了很多文章,但找不到解决方法

解决方法

当涉及对象数组时,Vue确实具有一些棘手的行为。

Vue正在监视您的数组,并且在修改数组的.length或修改其值之一时,vue可以“看到”该更改。

当您更新数组中对象的字段时,您将不会获得反应性,因为对Vue而言,数组未更改。这是因为数组的值是对对象的引用,并且在更新对象时,这些引用不会更改。

您的上述方法对我来说似乎不错,但同样可能存在一些奇怪的问题。

我将重点介绍两种工具来解决这些反应性问题。我认为,第一种方法对您的情况更好。

  1. 明确修改数组的长度。
updatePublication(index,editedPublication) {
    this.deletePublication(index);
    this.addPublication(index,editedPublication);
}
  1. 使用:key强制重新渲染。当模板中的键发生更改时,它将强制重新渲染所有子元素。
<template>
    <div class="main" :key="'updated-'+updated">
    ...
</template>
    data() {
        return {
            updated: 0,};
    },...

    updatePublication(index,editedPublication) {
        this.publications.splice(index,1,editedPublication);
        this.updated++;
    }