Bootstrap

ant-design-vue 实现表格内部字段验证

ant-design-vue 实现表格内表单字段验证

表格内 column 可输入的需求还是很常见的,尤其有一些业务场景就是表单内部有一个表格,然后表格的某些列是个进行输入的,就像下面这样

  • 下单数量 内容不能为空
  • 下单数量 必须输入正整数
    在这里插入图片描述

翻阅 ant-design-vue 官网并没有发现说表单内表格字段验证的方案,但是有一个 自行处理表单数据 的介绍
image.png

那我们是不是可以参考这个方案去实现咱自己的业务需求呢,下面就开始说一下实现方案

<a-table
  :columns="columns"
  bordered
  :rowKey="col => col.id"
  :dataSource="tableData"
>

  <a-form-item 
    :label-col="{
      xs: { span: 0 },
      sm: { span: 0 },
    }"
    :wrapper-col="{
      xs: { span: 24 },
      sm: { span: 24 },
    }"
    :validate-status="getFildStatus(record.id).validateStatus"
    :help="getFildStatus(record.id).errorMsg"
    slot="goodModelCount" 
    slot-scope="text, record">
    <a-input
      style="width: 100%"
      :min="1"
      v-model="text.goodModelCount"
      @change="handleChange(text.goodModelCount, record.id)"
    />
  </a-form-item>

  <div slot="action" slot-scope="text, record">
    <a href="javascript:;"><a-icon type="delete" /></a>
  </div>
</a-table>
<script>
const columns = [
  { title: '商品名称', dataIndex: 'id', align: 'center' },
  { title: '商品型号', dataIndex: 'account', align: 'center' },
  { title: '型号价格', dataIndex: 'area', align: 'center' },
  { title: '下单数量', key: 'goodModelCount', align: 'center', width: '200px', scopedSlots: { customRender: 'goodModelCount' }, align: 'center', },
  { title: '操作', scopedSlots: { customRender: 'action' }, width: '150px',  align: 'center',}
]

function validatePrimeNumber(number) {
  if (/^[1-9]\d*|0$/.test(number)) {
    return {
      validateStatus: 'success',
      errorMsg: '',
    };
  }
  return {
    validateStatus: 'error',
    errorMsg: '下单数量不能为空',
  };
}
export default {
  name: 'order-dialog',
  data() {
    return {
      visible: true,
      labelCol: {
        xs: { span: 24 },
        sm: { span: 7 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 12 },
      },
      form: this.$form.createForm(this),
      validatorRules: {
        consigneeName: {
          rules: [
            { required: true, message: '请输入收货人姓名' }
          ]
        },
        consigneePhone: {
          rules: [
            { required: true, message: '请输入收货人联系电话' }
          ]
        },
        addresseeAddressDetail: {
          rules: [
            { required: true, message: '请输入收货地址详情' }
          ]
        }
      },
      columns: columns,
      tableData: [{ id: 1, account: 123, area: 123, goodModelCount: 3434}, { id: 2, account: 123, area: 123, goodModelCount: 111}],
      goodModelCountData: []
    }
  },
  methods: {
    getFildStatus(id) {
      const data = this.goodModelCountData.filter(item => id === item.id)[0]
      if (data) {
        return data
      } else {
        return {
          errorMsg: '',
          validateStatus: 'success'
        }
      }
    },

    handleChange(value, id) {
      const newData = [...this.tableData];
      const target = newData.filter(item => item.id === id)[0]
      if (target) {
        const { errorMsg, validateStatus } = validatePrimeNumber(value)
        let flag = true
        this.goodModelCountData.forEach(val => {
          if (val.id === id) {
            flag = false
            val.errorMsg = errorMsg,
            val.validateStatus = validateStatus
          }
        })

        if (flag) {
          this.goodModelCountData.push({
            id,
            errorMsg,
            validateStatus
          })
        }
        target.goodModelCount = value
        this.tableData = newData
      }
    },
    handleOk() {
      this.visible = false
    }
  }
}
</script>

重点注意两个属性:

  • validate-status 校验状态,可选 ‘success’, ‘warning’, ‘error’, ‘validating’
  • help 设置校验文案

vue 里面是允许我们在属性里面以 函数 的形式返回属性的,所以我们可以把验证规则放到函数里里面 validatePrimeNumber (函数名字最好还是语义化明确一些,我这边直接复制的官方文档上的)

需要进行验证的字段(需要在 a-table 标签内部)

<a-form-item 
  :label-col="{
    xs: { span: 0 },
    sm: { span: 0 },
  }"
  :wrapper-col="{
    xs: { span: 24 },
    sm: { span: 24 },
  }"
  :validate-status="getFildStatus(record.id).validateStatus"
  :help="getFildStatus(record.id).errorMsg"
  slot="goodModelCount" 
  slot-scope="text, record">
  <a-input
    style="width: 100%"
    :min="1"
    v-model="text.goodModelCount"
    @change="handleChange(text.goodModelCount, record.id)"
  />
</a-form-item>

当我们输入框进行输入的时候我们就会出发 handleChange 方法,在方法里里面我们去进行输入内容的验证,然后根据id从 getFildStatus 找到当前对象,然后进行验证。

如果列表内有多列需要进行验证,那么就需要主要这个数据格式怎么定了了,根据实际需求进行参考

;