在andv的Table中使用表单控件并进行校验的小技巧

1,947 阅读2分钟

背景

当我们用 ant-design-vueTable 控件,并且其中的某些列是表单控件时候,官方文档中并没有给出可以定义列的校验规则的示例,那么我们怎么办呢?(ui要求只要控件有红色border即可)

实现原理

ant-design-vue 的表单控件在form中为什么会标红呢? 底层它使用了 async-validator ,然后会将有错误的form-item上增加一个class : ant-form-item-has-error。那么我们只要在自己的表单控件外的容器dom上动态增减这个class即可做到标红了。

实现步骤

我们的列的控件是通过Table控件的插槽实现的:

<template #field_name="{ record }: { record: RowItem }">
  <a-input
	v-model:value="record.field_name"
	placeholder="请输入"
  />
</template>

我们先为其增加一个容器dom:

<template #field_name="{ record }: { record: RowItem }">
	<div :class="{
		'ant-form-item-has-error': !record.validate.field_name,
	  }"
    >		
	  <a-input
		v-model:value="record.field_name"
		placeholder="请输入"
	  />
  </div>
</template>

这个dom的class由一个新增的boolean来决定,字段的名字和控件的value保持一致,然后在行数据的建模上进行修改:

export class RowItem {
    field_name: string
++  validate: {
++    field_code: boolean
++  }
    constructor(args: Partial<RowItem> = {}) {
      this.field_name = args.field_name ?? ''
      // 默认值是true,用户还没输入时显示校验通过
++    this.validate = {
++      field_code: true,
++    }
    }
}

现在属性有了,我们需要加上修改校验结果的代码,先来想一下都有哪几种情况:

  1. 当某行某列的控件显示标红,用户手动输入后,应该变为校验通过
  2. 当点击下一步时候,收集所有的控件,判断是否都已经非空了
  3. 用户进页面直接点击下一步,此时所有的validate都为true,但是它们值却是空的,需要特殊处理

第一个功能点很好写:

<a-input
    v-model:value="record.field_name"
    placeholder="请输入"
    @change="record.validate.field_name = !!record.field_name"
/>

第二和第三个功能点是在一起的:

const validate = async () => {
  // 解决第三个功能点,确保validate结果是真实的
  dataSource.value.forEach(record => {
    record.validate.field_name = !!record.field_name
  })
  return dataSource.value.every(record => record.validate.field_name )
}

如果想校验更多列,就继续扩展validate属性,这也是将其设置为对象的原因

最终效果

完结撒花