通过一个歪门邪道的方式可以实现在表单内的a-upload发生实时校验,首先写一个antUploadImg.vue组件,dom内容大致如下:
<a-upload
name="file"
:customRequest="handleCustomRequest"
:before-upload="handleBeforeFileUpload"
:showUploadList="true"
list-type="picture-card"
v-bind="$attrs"
v-model:file-list="fileList"
@change="handleChange"
@preview="handlePictureCardPreview">
<div v-if="fileList?.length < $attrs.maxCount">
<plus-outlined />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
然后是antUploadImg.vue组件内比较关键的部分,就是一旦绑定的fileList的值改变了,要通过change事件传递出去,(请注意,computed值,只能改变,比如改变数组用push,不能直接重新赋值,它的本质是依赖的值变了就跟随变化,变了之后就会触发所依赖值的set方法):
const emits = defineEmits(['update:value','change']);
const fileList = computed({
get: () => props.value,
set: (val) => {
emits('update:value', val)
emits('change', val)
},
});
在自定义的上传方法handleCustomRequest里,拿到上传的接口返回值之后,更新fileList:
// 上传成功拿到返回值之后
fileList.value.push(res.data);
emits('change', fileList.value)
在要使用的地方引入,(最好换个名字,免得跟antd自带的组件名重复了):
import UploadImgs from '@/components/Upload/antUploadImg'
使用的地方,dom写法:
<a-form-item
label="活动封面图"
name="coverImg"
:rules="[{ required: true,
validator: validateCoverImg, trigger: 'change'
}]">
<UploadImgs v-model:value="editFormVal.coverImg" :maxCount="1"></UploadImgs>
</a-form-item>
自定义校验方法,注意点已经注释说明了
const validateCoverImg = async (rule, value) => {
if (value.length == 0) {
// 其实此时可能上传过了,图片也返回了,只是length仍未更新。
return new Promise((resolve, reject) => {
// 这里一定要有定时器,因为antd上传组件的数据更新有点迟
setTimeout(() => {
if (value.length) {
resolve();
}else{
reject('请上传封面图');
}
}, 1500);
});
} else {
editFormRef.value.clearValidate('coverImg')
return Promise.resolve();
}
};