最近换了新工作,新公司的主要开发框架使用 antd 的 ui 库进行开发,其中 <a-form> 的校验小红星就是出不来,经过探索和网上搜索发现,antdv 中的 <a-form> 校验方式和熟悉的 element ui 的校验方式有一些区别,具体体现在 antd 主要是使用 <a-form> 自带的 v-decorator 属性进行校验,而不是使用 element ui 的 <el-form-item> 标签中的 ref 进行绑定校验。
<!--@author: fuyucong(congreat)-->
<!--@description: 添加升级包抽屉-->
<template>
<a-drawer
:title="title"
:width="width"
placement="right"
:closable="false"
@close="close"
destroyOnClose
:visible="modelVisible">
<div class="tips-container">请添加要升级至的目标版本的完整的升级包</div>
<a-form :form="form" :labelCol="labelCol" :wrapperCol="wrapperCol" @submit="submitForm">
<a-form-item label="升级包名称">
<a-input
v-decorator="['name', { rules: [{ required: true, message: '请输入升级包名称' }] }]"
placeholder="请输入升级包名称"/>
</a-form-item>
<a-form-item label="选择产品">
<a-select
v-decorator="['productId', { rules: [{ required: true, message: '请选择产品' }] }]"
placeholder="请选择产品"
>
<a-select-option v-for="item in productList" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="目标版本">
<a-input
v-decorator="['version', { rules: [{ required: true, message: '请输入目标版本' }] }]"
/>
</a-form-item>
<a-form-item label="验证状态">
<a-radio-group
v-decorator="['verify_state', { rules: [{ required: true, message: '请选择验证状态' }] }]"
>
<a-radio :value="1">需要验证</a-radio>
<a-radio :value="0">不需验证</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="上传升级包">
<a-upload
v-decorator="['file', { rules: [{ required: true, message: '请上传升级包' }] }]"
name="file"
:multiple="true"
:showUploadList="false"
accept=".rar,.zip,.bin"
:customRequest="fileUpload"
:beforeUpload="beforeUpload"
>
<a-button>
<a-icon type="upload"/>
选择文件
</a-button>
</a-upload>
</a-form-item>
</a-form>
<div class="drawer-footer">
<a-button @click="close" style="margin-bottom: 0;">关闭</a-button>
<a-button v-if="!disableSubmit" @click="submitForm" type="primary" style="margin-bottom: 0;">提交</a-button>
</div>
</a-drawer>
</template>
<script>
import productService from '@api/biz/product'
import deviceOtaService from '@api/biz/deviceOta'
export default {
name: 'addFirmware',
props: {
visible: {
type: Boolean,
default: false
},
disableSubmit: {
type: Boolean,
default: false
},
},
data() {
return {
title: '添加升级包',
width: 650,
labelCol: {
span: 4,
offset: 2
},
wrapperCol: {
span: 17
},
productList: [],
param: {
module: 'default',
version: 'v'
},
form: this.$form.createForm(this),
}
},
created() {
},
mounted() {
this.getProductList()
},
computed: {
modelVisible: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
}
},
methods: {
close() {
this.$emit('close');
},
handleOk(values) {
// this.$emit('close');
let params = new FormData();
// params.name = new FormData().append('name', this.param.name)
// params.productId = new FormData().append('productId', this.param.productId)
// params.version = new FormData().append('version', this.param.version)
// params.module = new FormData().append('module', this.param.module)
params.append('name', values.name)
params.append('product_id', values.productId)
params.append('version', values.version)
params.append('module', 'default')
params.append('file', this.param.file)
params.append('verify_state', values.verify_state)
console.log(params, 'params')
deviceOtaService.addFirmwares(params).then(res => {
if (res.code === 0) {
this.$message.success('添加成功');
this.$emit('close');
}
})
},
getProductList() {
productService.getProductList({
page_index: 1,
page_size: 1000
}).then(res => {
if (res.code === 0) {
this.productList = res.data.data
}
})
},
async fileUpload(info) {
this.param.file = info.file;
},
beforeUpload(file) {
const isRar = file.type === '';
const isBin = file.type === 'application/octet-stream';
const isZip = file.type === 'application/x-zip-compressed';
let isType = isRar || isBin || isZip;
if (!isType) {
this.$message.error('只能上传rar、bin、zip格式的文件!');
}
const isLt30M = file.size / 1024 / 1024 < 30;
if (!isLt30M) {
this.$message.error('文件大小不能超过30MB!');
}
return isType && isLt30M;
},
upload(file){
return new Promise(resolve=>{
let reader = new FileReader()
reader.readAsBinaryString(file);//读取文件的原始二进制数据
reader.onload = ev=>{
resolve(ev.target.result)
}
})
},
submitForm() {
this.form.validateFields((err, values) => {
if (!err) {
this.handleOk(values)
}
})
}
}
}
</script>
校验的重点在于在 <a-form> 标签中的 :form="form" 绑定值
<template>
<a-form
:form="form"
@submit="submitForm"
>
<!-- 不要绑定 ref!不要绑定 v-model! -->
<a-form-item label="目标版本>
<a-input
v-decorator="['version', { rules: [{ required: true, message: '请输入目标版本' }] }]"
/>
</a-form-item>
</a-form>
</template>
<script>
export default {
data() {
return {
form: this.$form.createForm(this) // 在此使用createForm方法绑定this,会自动创建this.form
}
},
methods: {
submitForm() {
this.form.validateFields((err, values) => {
if (!err) { // 校验通过
console.log(values) // form中的值会通过values返回
}
}
}
}
}
</script>
切记:如果使用此种方法校验,不要在 <a-form-item> 上绑定 ref ,也不要在 <a-form-item> 中的元素(如 <a-input> 、<a-select> 等)中绑定 v-model ,否则会报错!