使⽤async-validator⾃定义校验规则实现table组件的循环表单
校验功能
⾸先我们构建表单的 dom 元素,这⾥我们使⽤的是 render 函数代替 template,利⽤ scopedSlots 字段向⼦组件中传⼊⼀个作⽤域插槽的对象。
<a-table
rowKey={(record, index) => index + record.varietyCode}
pagination={false}
data-source={this.tableData}
columns={columns.call(this, h)}
{...{ scopedSlots: this.scopedSlotsList }}
/>
由于不同的 mode 形式下,可能 column 项是可编辑的,也有可能是不可以编辑,只能查看相关数据的。
const validators = []
scopedSlotsList () {
const obj = {}
Array.prototype.forEach.call(['applyAssistQty'], item => {
obj[item] = (text, record, index) => {
return (['edit', 'add'].de) || (record.waitInfo === true && de === 'tracking'))
<cell-validate mode="a-input-number"
validateProp={`${item}${index}`}
validators={validators}
rules={[{ required: true, message: '该选项必填' }, {
validator: (rule, value, callback) => {
......
return callback()
},
}]}
v-model={this.tableData[index][item]} />
: text
}
})
}
我们可以看到上述 cell-validate 组件就是我们要实现的表单校验功能组件。
mode: 标签名或组件名
validateProp:校验组件的 prop 属性,由于是循环表单,我们添加了 index 的值
validators:要校验的组件
rules: 校验规则
同时向外还提供了两个⽅法:validate 和 clearValidate
validate: ⽤来校验
clearValidate ⽤来清空校验规则
async validate () {
try {
await Promise.all([...validators.map(vm => vm.validate())])
return true
} catch (err) {
return false
}
}
async clearAllValidate () {
await [...validators.map(vm => vm.clearValidate())]
},
接下来就是如何实现 cell-validate 组件?
我们再来回顾下 async-validator 的基本⽤法:。
validate 校验表单⽅法就是采⽤ async-validator 的基本⽤法实现的,使⽤ errorMessage 记录错误信息,清空校验只需将errorMessage 清空即可。
validate () {
// 真正校验的的时候再⽣成validator函数
if (!this.validateProp || !this.rules) solve(true)
const descriptor = {
[this.validateProp]: this.rules,
}
const validator = new Schema(descriptor)
if (!validator) solve(true)
const model = {
[this.validateProp]: this.$attrs.value,
}
return validator.validate(model, (errors, fields) => {
})
},
clearValidate () {
},
我们可以看到我们使⽤的 validators 是由验证表单内部创建的。
created () {
this.validators.push(this)
},
beforeDestroy () {
const index = this.validators.findIndex(vm => vm._uid === this._uid)
if (index >= 0) {
this.validators.splice(index, 1)
}
},
由于传⼊的⾃⼰⾃⾝有⼀些 attribute 和 事件,在添加校验规则的同时如何拥有组件⾃⾝的属性呢?我们将使⽤ $attrs  和 $listeners 来获取。详情请查看:。
return <div class={Message ? 'has-error' : ''} >
{
de,
{
style: {
width: '100%',
},
props: {
...this.$attrs,
dropdownMatchSelectWidth: false,
},
on: {
...this.$listeners,
select: (param) => this.$emit('select', param),
change: this.handleChange,
},
}
)
}
{ Message && <span >{Message}</span> }
</div>
},
进阶版:
如何给选中的 table ⾏添加校验规则,未选中的⾏则取消校验规则呢?
由于校验规则是通过组件外部传⼊的,所以在添加出做校验规则那⾥只需做判断处理即可。
scopedSlotsList () {
const obj = {}
Array.prototype.forEach.call(['weight'], item => {
obj[item] = (text, record, index) => {
return <cell-validate mode="a-input-number" class="w140"
validateProp={`${item}${index}`}
validators={validators}
rules={this.asyncRules(record, item)}
v-model={this.tableData[index][item]} />
}
})
return obj
},
我们可以上述的校验规则是由 asyncRules 所产⽣的。这⾥的 asyncRules 可以使⽤计算属性也可以使⽤⽅法实现。对于勾选的数据则返回校验规则即可,未勾选的返回 null。
return function (record, key) {
if (this.selectedRowKeys.includes(record.id) && ['weight'].includes(key)) {      return {
const的作用
validator: (rule, value, callback) => {
......
return callback()
},
}
}
return
}
},
// 组件 validate 校验⽅法
validate () {
// 真正校验的的时候再⽣成validator函数
if (!this.validateProp || !this.rules) solve(true)
......
},

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。