Vue3中如何删除嵌套对象数组内的指定LABOR/PART元素?
问题:无法删除订单表单中指定Job下的单个Labor行
我开发的订单表单支持以下功能:
- 添加Job,每个Job可拆分为多行Labor和Part,结构示例:
JOB1 - LABOR1 - LABOR2 - PART1 - PART2 JOB2 - LABOR1 - LABOR2 - PART1 - PART2 - 数据采用对象数组结构:外层是
jobs数组,每个Job对象包含jobLabor和jobPart两个子数组。
目前添加Job、Labor、Part的功能都正常,但无法从指定Job的jobLabor数组中删除单个Labor行。相关代码如下:
const jobs = ref([ { jobId: idGen(), // idGen() 是生成唯一ID的工具函数 jobTitle: 'Job 1', jobLabor: [], jobPart: [] } ]) const addJob = () => { // 该函数正常工作,可添加新Job jobs.value.push({ jobId: idGen(), jobTitle: 'New Job', jobLabor: [], jobPart: [] }) } const addLabor = (addToJobId) => { const job = jobs.value.filter(job => jobId === addToJobId) job[0].jobLabor.push({ laborId: idGen(), description: '', quantity: 1, amount: 0 // 该函数可给指定Job添加Labor行 }) } const addPart = (addToJobId) => { const job = jobs.value.filter(job => jobId === addToJobId) job[0].jobPart.push({ laborId: idGen(), description: '', quantity: 1, amount: 0 // 该函数可给指定Job添加Part行 }) } const deleteJob = (deleteJobId) => { // 该函数可删除整个Job jobs.value = jobs.value.filter(job => job.jobId !== deleteJobId) if (jobs.value.length === 0) { addJob() } // 确保表单不会为空 } const deleteLaborLine = (deleteFromJobId, deleteLaborId) => { const job = jobs.value.filter(job => job.jobId === deleteFromJobId) job[0].jobLabor.filter(labor => labor.laborId !== deleteLaborId) }
问题分析与修正
deleteLaborLine函数无法工作的核心问题有两个:
- 拼写错误:原代码中曾将参数
deleteFromJobId误写为dleteFromJobId,导致无法匹配到目标Job,修正拼写后可正确定位到目标Job。 - 未修改原数组:
filter方法会返回一个新数组,但不会修改原数组。因此需要将过滤后的结果重新赋值给job[0].jobLabor,才能真正删除指定的Labor行。
修正后的deleteLaborLine函数如下:
const deleteLaborLine = (deleteFromJobId, deleteLaborId) => { // 用find代替filter更高效,因为jobId是唯一的,只会返回一个结果 const job = jobs.value.find(job => job.jobId === deleteFromJobId) if (job) { job.jobLabor = job.jobLabor.filter(labor => labor.laborId !== deleteLaborId) } }
另外补充对应的deletePartLine函数,逻辑完全一致:
const deletePartLine = (deleteFromJobId, deletePartId) => { const job = jobs.value.find(job => job.jobId === deleteFromJobId) if (job) { job.jobPart = job.jobPart.filter(part => part.laborId !== deletePartId) // 注意:Part对象的ID字段命名为laborId容易混淆,建议统一改为partId } }
额外优化点
- 在
addLabor和addPart函数中,使用find代替filter更高效,因为jobId是唯一的,不需要返回数组,直接获取单个Job对象即可:const addLabor = (addToJobId) => { const job = jobs.value.find(job => job.jobId === addToJobId) if (job) { job.jobLabor.push({ laborId: idGen(), description: '', quantity: 1, amount: 0 }) } } - Part对象中的ID字段命名为
laborId容易混淆,建议改为partId,保持命名一致性。
内容的提问来源于stack exchange,提问作者Ralph Llanes
相关产品推荐
相关产品推荐

