1

我的应用程序结构看起来像这样

App
    Column Component
        Task Component
        Task Component
        Task Component
    Column Component
        Task Component
        Task Component
    Column Component
    Column Component

在此处输入图像描述

每列都有一个<draggable>围绕任务的组件。在应用程序级别,我有一个数据对象,其中包含不同的列,每列都有其任务。

data: function() {
    return {
        columns: {
            new: [
                {
                    ID: 1,
                    title: 'The thing',
                    description: 'Prepare a proposal for facade'
                },
                {
                    ID: 2,
                    title: 'The thing 2',
                    description: 'Prepare a proposal for facade'
                },
                {
                    ID: 3,
                    title: 'The thing 3',
                    description: 'Prepare a proposal for facade'
                }
            ],
            inProgress: [
                {
                    ID: 4,
                    title: 'The thing 4',
                    description: 'Prepare a proposal for facade Store Opening Process (DEMO)'
                },
                {
                    ID: 5,
                    title: 'The thing 5',
                    description: 'Prepare a proposal for facade Store Opening Process (DEMO)'
                }
            ],
            done: [],
            onHold: []
        }
    }
}

我遍历列,并将对象绑定到组件:

<kool-column
    v-for="column"
    v-bind="colum"
></kool-column>

Kool Column 组件:

<script id="kool-column-template" type="text/x-template">
    <div>
        <div>
            {{ column.name }} ({{ column.cards.length }})
        </div>
        <div>
            <draggable v-model="cards" group="columnkool">
                <div v-for="card in cards" :key="card.ID">
                    <kool-card v-bind="card"></kool-card>
                </div>
            </draggable>
        </div>
    </div>
</script>

<script>
    $(document).ready(function() {
        Vue.component('koolColumn', {
            template: '#kool-column-template',
            props: {
                ID: {
                    type: Number,
                    required: true
                },
                name: {
                    type: String,
                    required: true
                },
                cards: {
                    type: Array,
                    default: function() { return []; }
                }
            }
        });
    });
</script>

所以,我的问题是,当我拖放卡片时,会收到 Vue 错误/警告:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "cards"

有道理,我一直在阅读和调查,在 Vue 中,您想使用 props 将数据向下传递到组件中,但是为了修改这些数据,您向父级发送一个事件,并让父级对其进行修改。

好的,但是我正在使用Vue Draggable的库修改了我通过它的列表。所以我该怎么做?我认为的解决方案:

  1. 在挂载列组件时,将道具卡复制到组件的数据中,将其用于列表和修改,每次更改时,将新列表发送给父级。我认为这没有多大意义,我会有两个信息来源(app 对象中的卡片和我的列组件对象中的卡片),并且存在它们未对齐的风险,毕竟我正在更新列表分别地。
  2. 删除项目时,使用库实际上“不允许”删除(您可以使用库事件并返回 false,因此它实际上不会更改列表)。捕捉事件,将拖动的项目的信息发送给父级,用户是否试图放下它并相应地更改数据。基本上,我会使用拖放库来了解用户试图将某些东西放在哪里,并实际手动更改数据。这看起来也很奇怪,代码真的很难理解,并且在放下物品时会闪烁(因为它会回到原来的位置,然后回到你想要的位置)。
  3. 另一个不好的解决方案是传递给列组件,而不是单独的 v-bind 和每个属性,而是整个对象。因此,实际上使 Vue 警告消失并保持双重数据绑定的不是v-bind="colum"我这样做。:column="column"问题是,我正在做反模式,没有警告,但仍然......(顺便说一句,这种方法来自这个例子:Task management using Vue

我应该继续使用方法#2吗?,丑陋但至少不是反模式,也不会加倍信息。或者当我不在“控制”正在更新的列表时,是否有另一种保持双重数据绑定的方法?或者也许只是应用程序的不同架构/结构?

4

1 回答 1

0

Vue draggable有两种处理提供的数据的方式:

  1. 使用v-model="array",这是不可变的 - 如果项目的顺序发生变化,它会创建一个新副本。
  2. using :list="array",这使用相同的引用并使用 splice 来更新数组。

在你的情况下,使用:list="array",你应该没问题。

于 2021-05-28T12:19:16.573 回答