1、此功能已集成到TTable组件中
2、最终效果
3、使用方式
1、第一种方式(全量配置,rules配置方式继承el-form)
table: { rules: { hobby: [{ required: true, message: '请至少选择一个爱好', trigger: 'change' }], year: [{ required: true, message: '请选择年份', trigger: 'change' }], name: [{ required: true, message: '请输入姓名', trigger: 'blur' }], }, .... }
复制
2、第二种方式(单项配置(即在columns中某一项配置),rules配置方式继承el-form-item)
columns: [ { prop: 'unit', label: '单位', minWidth: '220', canEdit: true, headerRequired: true,// 是否显示必填红点 configEdit: { label: '单位', append: '吨', // 单项规则配置 rules: { required: true, message: '请输入单位', trigger: 'blur' }, bind: { 'prefix-icon': 'el-icon-search' }, editComponent: 'el-input' } }, ]
复制
3、校验错误提示(validateError事件)
注意:
1、必须是调用了save方法,才会触发validateError事件
2、validateError事件返回每项校验不通过的 label 集合——对应columns每项prop的label
4、具体实现
<!-- TTable组件 --> <template v-if="item.canEdit"> <el-form :model="tableData[scope.$index]" :rules="isEditRules?table.rules:{}" :ref="`formRef-${scope.$index}-${item.prop||scope.column.property}`" > <!-- 单个单元格编辑组件 --> <single-edit-cell :configEdit="item.configEdit" v-model="scope.row[scope.column.property]" :prop="item.prop" :tableData="tableData" :record="scope" @handleEvent="(event,model) => $emit('handleEvent',event,model,scope.$index)" @Keyup="handleKeyup" v-on="$listeners" v-bind="$attrs" ref="editCell" > <!-- 遍历子组件非作用域插槽,并对父组件暴露 --> <template v-for="(index, name) in $slots" v-slot:[name]> <slot :name="name" /> </template> <!-- 遍历子组件作用域插槽,并对父组件暴露 --> <template v-for="(index, name) in $scopedSlots" v-slot:[name]="data"> <slot :name="name" v-bind="data"></slot> </template> </single-edit-cell> </el-form> </template>
复制
<!-- single-edit-cell组件 --> <template> <el-form-item :prop="record.column.property" :rules="configEdit.rules" :class="[configEdit.className,'single_edit_cell']" v-bind="$attrs" v-on="$listeners" > .... </el-form-item> </template>
复制
5、关键代码(save方法)
computed: { // 单元格编辑是否存在校验 isEditRules() { return (this.table.rules && Object.keys(this.table.rules).length > 0) || this.columns.some(item => item?.configEdit?.rules) } }, methods:{ // 单行编辑&整行编辑返回数据 save() { if (!this.isEditRules) { this.$emit('save', this.tableData) return this.tableData } /** * 表单规则校验 */ let successLength = 0 let rulesList = [] let rulesError = [] let propError = [] let propLabelError = [] // 获取所有的form ref const refList = Object.keys(this.$refs).filter(item => item.includes('formRef')) // 获取单独设置规则项 const arr = this.renderColumns.filter(val => { if (val.configEdit?.rules) { return val } }).map(item => item.prop) // 获取整体设置规则 const arr1 = this.table.rules && Object.keys(this.table.rules) // 获取最终设置了哪些规则(其值是设置的--prop) const newArr = [...arr, ...arr1] // 最终需要校验的ref newArr.map(val => { refList.map(item => { if (item.includes(val)) { rulesList.push(item) } }) }) console.log('最终需要校验的数据', rulesList) // 表单都校验 rulesList.map(val => { this.$refs[val].map(item => { item.validate((valid) => { if (valid) { successLength = successLength + 1 } else { rulesError.push(val) } }) }) }) // 所有表单都校验成功 if (successLength === rulesList.length) { if (this.isEditRules) { this.$emit('save', this.tableData) return this.tableData } } else { // 校验未通过的prop rulesError.map(item => { newArr.map(val => { if (item.includes(val)) { propError.push(val) } }) }) // 去重获取校验未通过的prop--label Array.from(new Set(propError)).map(item => { this.renderColumns.map(val => { if (item === val.prop) { propLabelError.push(val.label) } }) }) console.log('校验未通过的prop--label', propLabelError) this.$emit('validateError', propLabelError) } }, }
复制
6、demo地址
GitHub源码地址
Gitee源码地址
相关文章
基于ElementUi或Antd再次封装基础组件文档
vue3+ts基于Element-plus再次封装基础组件文档
TTable组件封装地址