需求
根据 Table 表格内的复选框来控制当前选中行是否添加必填校验规则
效果图
实现思想
我们需要设置一个 flag 来标识已勾选的行,el-table渲染数据结构是数组对象形式,我们可以在每个对象中手动加如一个标识,例如默认:selected : false,如你的源数据中已有类似key,则可用它作于唯一标识
重要代码部分
html代码
<template><div><el-form :model="productInfoForm" ref="productInfoFormRef" :rules="productInfoRules"><el-table ref="multipleTableRef" :data="productInfoForm.skuList" @select-all="handleSelectionChangeAll"@select="handleSelection" @selection-change="handleSelectionChange"><!-- 复选框 --><el-table-column type="selection" width="55" /><!-- 需要动态设置校验项 --><el-table-column><template #header><div><span v-text="`您的售价`"></span></div></template><template #default="scope"><div><el-form-item :ref="`unitPrice_${scope.$index}`" :prop="`skuList.${scope.$index}.unitPrice`":rules="getRules(scope.row.selected, scope.$index, 'unitPrice')"><div class="flex-box"><p class="fs-12 flex-shrink" v-text="`产品单价`"></p><el-input v-model="scope.row.unitPrice" placeholder="0"@blur="(e: Event) => { scope.row.unitPrice = (e.target as HTMLInputElement).value }"><template #prefix><span v-text="`¥`"></span></template></el-input></div></el-form-item><el-form-item :ref="`operationFee_${scope.$index}`" :prop="`skuList.${scope.$index}.operationFee`":rules="getRules(scope.row.selected, scope.$index, 'operationFee')"><div class="flex-box"><p class="fs-12 flex-shrink" v-text="`操作费`"></p><el-input v-model="scope.row.operationFee" placeholder="0"@blur="(e: Event) => { scope.row.operationFee = (e.target as HTMLInputElement).value }"><template #prefix><span v-text="`¥`"></span></template></el-input></div></el-form-item><el-form-item :ref="`finalDeliveryFee_${scope.$index}`" :prop="`skuList.${scope.$index}.finalDeliveryFee`":rules="getRules(scope.row.selected, scope.$index, 'finalDeliveryFee')"><div class="flex-box"><p class="fs-12 flex-shrink" v-text="`尾程派送费`"></p><el-input v-model="scope.row.finalDeliveryFee" placeholder="0"@blur="(e: Event) => { scope.row.finalDeliveryFee = (e.target as HTMLInputElement).value }"><template #prefix><span v-text="`¥`"></span></template></el-input></div></el-form-item></div></template></el-table-column></el-table><!-- 操作按钮 --><div><el-button :disabled="createProductDisabled" plain v-text="`保存`" @click="saveProduct"></el-button><el-button :disabled="createProductDisabled" type="primary" v-text="`提交审核`" @click="saveProduct"></el-button></div></el-form></div>
</template>
js代码
<script setup lang="ts">
import { ElForm } from 'element-plus';
import { ref, reactive, toRefs, computed, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance() as ComponentInternalInstance;const productInfoFormRef = ref(ElForm)
const multipleTableRef = ref<any>()const data = reactive<any>({productInfoForm: {skuList: [{selected: false,unitPrice: '',operationFee: '',finalDeliveryFee: '',}]},productInfoRules: {unitPrice: {required: true,message: '请完善必须项',tirgger: ['blur', 'change']},operationFee: {required: true,message: '请完善必须项',tirgger: ['blur', 'change']},finalDeliveryFee: {required: true,message: '请完善必须项',tirgger: ['blur', 'change']},},createProductDisabled: true,
});
const { productInfoForm, productInfoRules, createProductDisabled } = toRefs(data);// 根据flag动态设置表单校验规则
const getRules = computed(() => (selected: boolean, index: number, type: string) => {nextTick(() => {if (proxy?.$refs[`${type}_${index}`] && !selected) {(proxy?.$refs[`${type}_${index}`] as any).clearValidate()}// console.log(proxy?.$refs[`${type}_${index}`]);})return selected ? productInfoRules.value[type] : {}
})//当选择项发生变化时会触发该事件
const handleSelectionChange = (valArr: any[]) => {createProductDisabled.value = valArr.length ? false : true
}//当用户手动勾选数据行的 Checkbox 时触发的事件
const handleSelection = (valArr: any[], row: { selected: boolean; }) => {row.selected = !row.selected
}//监听table全选
const handleSelectionChangeAll = (valArr: any[]) => {const skuList = productInfoForm.value.skuListskuList.forEach((i: { selected: boolean; }) => {i.selected = valArr.length ? true : false})
}//创建并提交审核商品
const saveProduct = async () => {productInfoFormRef.value.validate(async (valid: boolean, fields: any) => {if (valid) {// 表单验证通过后相关逻辑处理...} else {console.log('error submit!', fields);}})
}
</script><style scoped lang="scss"></style>