vue+element-ui el-table表格单元格编辑新增el-form表单规则校验功能(校验不通过错误提示;el-table结合el-form做单元格编辑校验功能)

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组件封装地址

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wocwin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值