进来看我套娃!Vue3实现Table嵌套 select 并单独校验...
前情提要
场景: 产品提出了一个套娃需求,但貌似也合理...画不多说,直接上原型。可以看到弹窗里是一个表单,其中一项内容以表格形式呈现以实现项目的多选,表格中每行又嵌套select,还需要对勾上的那行中的select做单独校验...
问题: 先将这个魔鬼需求拆成两步:首先肯定实现一个大表单,点击save后校验表单内容users 和project,然后在勾选的时候对那行的选择框进行校验..
Step 1:实现表单 对表单嵌套表格的数据进行校验
<template>
<el-form
ref="dialogFormRef"
:model="empowerForm"
label-position="top"
style="width: 100%"
:rules="rules"
>
<el-form-item label="Authorized Users" prop="authorizedUsers">
<el-select
v-model="empowerForm.authorizedUsers"
style="width: 100%"
placeholder="please select authorized Users"
>
</el-select>
</el-form-item>
<el-form-item label="Authorized Project" prop="authorizedProject">
<el-table
ref="multipleTableRef"
:data="projectData"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="Tool" prop="tool" />
<el-table-column prop="name" label="Project Name"/>
<el-table-column prop="key" label="Project Key" />
<el-table-column label="Permission" align="center" width="300">
<template #default="scope">
<el-select clearable v-model="scope.row.permission" placeholder="Select">
<el-option
v-for="(item, index) in scope.row.permissionList"
:key="index"
:label="item.name"
:value="item.type"
/>
</el-select>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</template>
element-plus提供了这个多选的函数,监听函数改变formdata就可以实现rule的校验..这个实现起来还是挺简单的~就挑关键信息写了~
const rules = ref({
authorizedUsers: [
{ required: true, message: "Please select User", trigger: "change" },
],
authorizedProject: [
{
required: true,
message: "Please select project",
trigger: "change",
},
],
});
const handleSelectionChange = (selection) => {
empowerForm.authorizedProject = selection;
};
Step 2 在勾选的时候对选中的行内select进行校验
校验肯定要么把这个select作为一个大的表单的一项,利用validateField进行校验,这就要求prop是不同的类似于:prop="'formData.'+scope.$index+'.permission'"
,但由于现在场景下table本身就已经是表单的一项,prop怎么写实在是绕不出来。。
换个思路..校验还可以是一个表单,利用动态ref对整个表单实现校验,这样貌似也可行,说干就干
<el-table-column label="Permission" align="center" width="300">
<template #default="scope">
<el-form
:model="scope.row"
:validate-on-rule-change="true"
:ref="(el) => setFormRefs(el, scope.row.id)"
>
<el-form-item
prop="permission"
:rules="[
{
required: true,
validator: checkPermission,
},
]"
>
<el-select
clearable
v-model="scope.row.permission"
placeholder="Select"
>
<el-option
v-for="(item, index) in scope.row.permissionList"
:key="index"
:label="item.name"
:value="item.type"
/>
</el-select>
</el-form-item>
</el-form>
</template>
</el-table-column>
在监听多选的事件里面利用ref对该行的表单进行校验,但是table监听多选事件并没有获得当前勾选到那行的参数,只能获取到一个勾选数组,而动态ref也是一个数组,所以利用唯一性id进行匹配校验。
//获取动态ref
const setFormRefs = (el, id) => {
if (el) {
permissionRefs.push({
id,
el,
});
}
};
//监听多选事件
const handleSelectionChange = (selection) => {
validatePermission(selection);
empowerForm.authorizedProject = selection;
};
//校验选中的行内表单
const validatePermission = (selection) => {
permissionRefs.map((ref) => {
if (selection.length) {
selection.map((item) => {
if (ref.id === item.id) {
ref.el.validate((valid) => {});
} else {
//清空未选择的校验信息
ref.el.clearValidate();
}
});
} else {
ref.el.clearValidate();
}
});
};
这样就实现了在勾选或者清除时对行内select的校验或者是校验的清除~
这样一个魔鬼需求一开始面对的时候确实感觉难以下手..(也有菜的原因)后来逐步解剖完成功能,最终实现了想要的效果~很有成就感哈哈哈
完结撒花🎉..
转载自:https://juejin.cn/post/7269962653795975183