【发布时间】:2021-03-08 12:24:49
【问题描述】:
我的应用程序结构看起来像这样
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 修改了我通过它的列表。所以我该怎么做? 我想到的解决方案:
- 在挂载列组件时,将道具卡复制到组件的数据中,用于列表和修改,每次更改时,将新列表发送给父级。我认为这没有多大意义,我会有两个信息来源(app对象中的卡片和我的列组件对象中的卡片),并且存在它们未对齐的风险,毕竟我正在更新列表分开。
- 当放置一个项目时,使用库实际上“不允许”放置,(您可以使用库事件并返回 false,因此它实际上不会更改列表)。捕捉事件,将拖动的项目的信息发送给父级,用户是否试图放下它并相应地更改数据。基本上,我会使用拖放库来了解用户试图将某些东西放在哪里,并实际手动更改数据。这看起来也很奇怪,代码真的很难理解,并且在放下物品时会闪烁(因为它会回到原来的位置,然后回到你想要的位置)。
- 另一个不好的解决方案是传递给列组件,而不是单独的 v-bind 和每个属性,而是整个对象。因此,我使用
:column="column"而不是v-bind="colum",这实际上使Vue 警告消失并保持双重数据绑定。问题是,我正在做反模式,没有警告,但仍然......(顺便说一句,这种方法来自这个例子:Task management using Vue)
我应该继续使用方法 #2 吗?虽然丑陋,但至少不是反模式,也不会使信息翻倍。或者当我不在“控制”正在更新的列表时,是否有另一种保持双重数据绑定的方法?或者只是应用的不同架构/结构?
【问题讨论】:
-
嗨 Joseph,遇到的问题与您的完全相同:我想在子表组件中包含 vue-dragable,我将“行”作为道具传递。我在道具的可变性方面面临同样的问题。您找到问题的答案了吗?你最后做了什么?看起来互联网没有提供很多关于处理子组件内部 vuue-draggable 的好方法的线索
-
嗨@SebT,我正在做我在帖子中写的解决方案3。
标签: javascript vue.js vuejs2 vuedraggable