Element表单嵌套树形表格的校验问题

普通嵌套

表单和表格是项目中最常见的项目,有时候就会遇到表格嵌套表单的情况,比如
在这里插入图片描述
这种形式的其实挺好处理的,如下:

<el-form
      :model="states"
      ref="tableFormRef"
      label-width="80px"
      label-position="top"
  >
<el-table :data="states.tableData"  row-key="id"  border  height="400px">
<el-table-column prop="unitDosage" label="单位用量" width="320">
    <template #header>
        <span>
            <span class="require-star">*</span>
            <span>单位用量</span>
        </span>
    </template>
    <template v-slot="{ row,$index }">
        <el-form-item
            :prop="`tableData[${$index}].unitDosage`"
            :rules="e_rule('required', '单位用量不能为空')"
        >
            <el-input-number
                v-model.trim="row.unitDosage"
                :clearable="false"
                placeholder="请输入"
                :controls="false"
                :min="0"
                :precision="3"
            />
        </el-form-item>
    </template>
</el-table-column>
const states=reactive({
   tableData:[]
})

就按照上面的这种格式写就可以实现,因为是平级的,在表单校验时可以很容易的在表格数组中找到属性的值。

树形表格嵌套

最近把又碰见了树形表格嵌套的形式,如下图:
在这里插入图片描述
然后呢,就按照老套路那样写,结果一直校验不通过。最后发现是绑定的属性不对。以下面的代码为例

let list = [
    {
        id: "1",
        children: [
            {
                id: "1-1",
                children: [],
            },
        ],
    },
];

id1-1的属性应该是list[0].children[0].id,所以问题就转换为如何获取到属性准确的路径问题
方法肯定是用递归,但是水平太低不会写(也就会写一点简单的递归)。

想到最近 new bing 这么火,我自己不会写,让new bing帮我写吧。结果真的给我写好了
在这里插入图片描述
当然 如果想要new bing给你答案的话,你需要准确的向他描述这个问题,你描述的越准确,他给你的答案越准确。反复尝试了很多次,最后给我了想要的答案。
下面是他给我的例子:

// 定义一个递归函数,接受一个对象或数组,一个目标id值和一个路径数组作为参数
function findPath(obj, targetId, path = []) {
        // 如果obj是数组,就遍历每个元素
        if (Array.isArray(obj)) {
            for (let i = 0; i < obj.length; i++) {
                // 将当前索引添加到路径数组中
                path.push(`[${i}]`)
                // 对当前元素递归调用findPath函数,并将结果赋值给result
                const result = BomTool.findPath(obj[i], targetId, path)
                // 如果result不为空,说明找到了匹配的id,就返回result
                if (result) return result
                // 否则,就从路径数组中移除最后一个元素(即当前索引)
                path.pop()
            }
        }
        // 如果obj是对象,就遍历每个属性
        else if (typeof obj === 'object') {
            for (const key in obj) {
                // 将当前键添加到路径数组中
                path.push(`.${key}`)
                // 对当前值递归调用findPath函数,并将结果赋值给result
                const result = BomTool.findPath(obj[key], targetId, path, key)
                // 如果result不为空,说明找到了匹配的id,就返回result
                if (result) return result
                // 否则,就从路径数组中移除最后一个元素(即当前键)
                path.pop()
            }
        }
        // 如果obj是基本类型(如字符串、数字等),就判断是否等于目标id
        else {
            // 如果相等,就将路径数组连接成字符串并返回
            if (obj === targetId) return path.join('')
            // 否则,就返回空字符串
            else return ''
        }
    }

// 定义一个测试用的列表对象
let list = [
    {
        id: "1",
        children: [
            {
                id: "1-1",
                children: [],
            },
        ],
    },
];

//删除最后的id
let str = findPath(list, "1-1")

// 调用findPath函数,并打印结果list[0].children[0].id
console.log(str);

这里需要注意一个问题,函数的值必须是唯一的。这里id是唯一的,最后返回值里有一个id,如果不是想要的属性的话,可以使用replace函数替换一下。
如果id值不是唯一的,这种情况也是会出现的。建议是往对象里再添加一个key,比如 key的值是id值加上当前的时间戳加上一个随机数拼接起来的字符串。

下面是在事件项目里应用的代码

<template v-slot="{ row }">
 <el-form-item
     :prop="`tableData${findPath(
         states.tableData,
         row.materialNo,
     ).replace('materialNo', 'unitDosage')}`"
     :rules="e_rule('required', '单位用量不能为空')"
     v-if="states.updateType != 'read'"
 >
     <el-input-number
         v-model.trim="row.unitDosage"
         :clearable="false"
         placeholder="请输入"
         :controls="false"
         :min="0"
         :precision="3"
     />
</el-form-item>

与上面提到平级基本一致,就是改一下prop属性值,下面看一下debugger的情况,可以看出路径是对的
在这里插入图片描述

补充

  • 根据路径获取层级的方法
findLevel(list, value) {
    const path = this.findPath(list, value)
    // 根据点的个数判断层级和序号
    let level = 0
    let index = 0
    if (path.length > 0) {
        level = (path.match(/]/g) || []).length
        index = parseInt(path.substring(path.lastIndexOf('[') + 1, path.length - 2)) + 1
    }
    return `${level}.${index}`
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值