对表格进行排序时,Vue v-for循环中的重复键
Posted
技术标签:
【中文标题】对表格进行排序时,Vue v-for循环中的重复键【英文标题】:Duplicate Keys in Vue v-for Loop When Table is Sorted 【发布时间】:2020-06-21 23:12:36 【问题描述】:我的 Vue 应用程序使用 vuefire 从 Firestore 导入数据。
我从“行”集合中导入数据,如下所示:
firestore()
return
lines: db.collection("lines")
每条记录都有一个 Firestore 生成的 id,然后我在 v-for 循环中使用一个键,例如:
<thead>
<tr>
<th>Code</th>
<th @click="sort_string(lines,'name')"> Name</th>
<th>Quantity</th>
</tr>
</thead>
<tbody v-for="line in lines" :key="line.id">
<tr>
<td>line.code</td>
<td>line.name</td>
<td>line.quantity</td>
<button @click="pick_one(line)">+1</button>
...
有一个方法pick_one
直接改变Firestore上的数量:
pick_one(line)
const new_quantity = line.quantity + 1;
db
.collection("lines")
.doc(line.id)
.update( quantity: new_quantity );
所有这些都可以正常工作直到我sort()
底层数组('lines')。
如果我对表进行排序,然后调用函数pick_one
,我会收到重复键错误:
[Vue warn]: Duplicate keys detected: 'RaTIINFWTQxHQPyRmfsQ'. This may cause an update error.
我只能假设这与 Vuefire 处理 update()
调用的方式有关,因为排序数组的行为不会导致这个问题,只是在排序时更新数组中的一行。
我的排序函数(vue方法)是这样的:
sort_string(table, column)
console.log("sorting")
this.sort_toggle = -this.sort_toggle;
return table.sort((a, b) =>
if (
a[column].toString().toUpperCase() <
b[column].toString().toUpperCase()
)
return -this.sort_toggle;
if (
a[column].toString().toUpperCase() >
b[column].toString().toUpperCase()
)
return this.sort_toggle;
return 0;
);
,
有没有办法避免这种行为?
【问题讨论】:
你能展示做排序的方法吗?并检查 Vuefire 在更新后是否返回相同的 id 我已更新问题以包含排序功能 你怎么打电话给sort_string
?那是方法还是计算属性?这可能与 Array.prototype.sort()
改变原始数组有关
在列标题中按上面编辑的问题排序:<th @click="sort_string(lines,'name')"> Name</th>
【参考方案1】:
Phil 的评论为这种行为提供了线索——sort()
函数正在处理基础数据而不是副本。
我已经修改了我的模板,以便 v-for now 循环遍历一个计算数组,该数组可以使用(稍微修改的)函数进行排序。
排序函数现在使用slice()
创建底层数组的副本:
computed:
sorted_lines()
return sort_string(lines, this.sort_column) // name of the column/filed to sort by
sort_string 函数现在看起来像这样(添加了slice()
sort_string(table, column)
console.log("sorting")
//this.sort_toggle = -this.sort_toggle; // moved elsewhere
return table.slice().sort((a, b) => // slice() then sort()
if (
a[column].toString().toUpperCase() <
b[column].toString().toUpperCase()
)
return -this.sort_toggle;
if (
a[column].toString().toUpperCase() >
b[column].toString().toUpperCase()
)
return this.sort_toggle;
return 0;
);
,
【讨论】:
以上是关于对表格进行排序时,Vue v-for循环中的重复键的主要内容,如果未能解决你的问题,请参考以下文章
无法在 vue.js 中的“v-for”(数据不可迭代)中对数据进行排序
Vue.js - 如何按特定属性对数组中的对象进行排序并使用“v-for”进行渲染