ant-design form表单校验upload组件(附个人封装的上传组件)
upload组件必填校验
最近一直在使用 ant-design 组件库开发,项目上突然说需要表单中上传附件为“必传”,遍访各大文档都没有答案,最后还是用自定义校验实现了这个需求。
使用 a-form-model 表单组件开发
<template>
<a-form-model ref="ruleForm" :rules="rules" :model="infoFrom">
<a-form-model-item label="上传附件" prop="files">
<a-upload
name="files"
:multiple="false"
:file-list="fileList"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
:headers="headers"
@change="handleChange"
>
<a-button> <a-icon type="upload" /> 上传附件 </a-button>
</a-upload>
</a-form-model-item>
<a-form-model-item>
<a-button type="primary" html-type="submit" @click="submitForm">
提交
</a-button>
</a-form-model-item>
</a-form-model>
</template>
<script>
export default {
data() {
return {
fileList: [],
rules: {
files: [{required:true, validator:this.uploadFileChange, trigger:'change'}]
}
}
},
methdos: {
// 自定义上传附件校验
uploadFileChange(rule, value, callback) {
if(this.fileList.length === 0) {
return callback('请选择需要上传的文件')
}else {
return true;
}
},
// 提交方法
submitForm() {
this.$refs.ruleForm.validate(valid => {
if (valid) {
console.log('触发保存');
}
})
}
}
}
</script>
个人封装上传附件
基于项目上的业务需求,二次封装了 ant-design 的 upload 组件,部分地方还没有做完成,后续完善后补充~
主文件
<!-- 上传文件升级版 -->
<template>
<div class="upload-container">
<a-upload-dragger
name="files"
:class="{'uploadHide': isState==='detail'}"
:disabled="disabled"
:list-type="fileListType"
:multiple="multiple"
:showUploadList="{
showPreviewIcon: isShowPreviewIcon,
showRemoveIcon: isShowRemoveIcon,
showDownloadIcon: isShowDownloadIcon
}"
:openFileDialogOnClick="true"
:headers="headers"
:file-list="fileList"
:data="data"
:action="uploadUrl"
:before-upload="beforeUpload"
@change="handleChange"
@preview="handlePreview"
@download="handleDownload"
>
<p class="ant-upload-drag-icon">
<a-icon type="inbox" />
</p>
<p class="ant-upload-text">
将文件拖拽此处上传
</p>
</a-upload-dragger>
<span class="upload-accept" v-if="isState!=='detail'">
<a-icon type="exclamation-circle" />
支持 {{ acceptHint }} 文件格式,最大不超过 {{ size }} M
</span>
</div>
</template>
<script>
import FileDetail from './file-detail'; // 在线预览组件,需调用业务内在线预览接口
export default {
name: "upload-plus",
props: {
// 上传文件状态 [detail(只读状态)、opera(操作状态)]
// detail(只读状态,必不显示删除按钮,仅显示查看和下载按钮)
isState: {
type: String,
default: ()=>{
return 'opera'
}
},
// 是否禁用附件上传
disabled: {
type: Boolean,
default: ()=>{
return false;
}
},
// 是否允许上传多个文件
multiple: {
type: Boolean,
default: ()=>{
return false;
}
},
// 限制文件上传个数
limit: {
type: Number,
default: ()=>{
return 0
}
},
// 允许上传的文件类型提示
accept: {
type: Array,
default: ()=>{
return ['doc','docx','xls','xlsx','jpg','jpeg','png','pdf','txt']
}
},
// 允许上传的文件大小提示(MB为单位)
size: {
type: Number,
default: ()=>{
return 200;
}
},
// 上传列表内建样式
fileListType: {
type: String,
default: ()=>{
return 'text';
}
},
// 是否显示预览图表
showPreviewIcon: {
type: Boolean,
default: ()=>{
return true
}
},
// 是否显示删除图表
showRemoveIcon: {
type: Boolean,
default: ()=>{
return true
}
},
// 是否显示下载图表
showDownloadIcon: {
type: Boolean,
default: ()=>{
return true
}
},
// 文件列表
fileList: {
type: Array,
default: () => {
return []
}
},
// 数据
data: {
type: Object,
default: ()=>{
return {}
}
},
// 上传文件的Url
uploadUrl: {
type: String,
default: ()=>{
return '/api/upload'
}
},
},
data() {
return {
// 文件请求头
headers: {
Authorization: 'Bearer ' + JSON.parse(localStorage.getItem('access-Token')).value,
}
}
},
computed: {
// 返回文件提示信息
acceptHint() {
if(this.accept.length === 0) {
return '未知';
}else {
if(this.accept.indexOf('*') === -1) {
return this.accept.join('、');
}else {
return '所有'
}
}
},
// 是否启用文件预览按钮
isShowPreviewIcon() {
return this.showPreviewIcon;
},
// 是否启用文件下载按钮
isShowDownloadIcon() {
return true;
},
// 是否启用文件删除按钮
isShowRemoveIcon() {
if(this.showRemoveIcon && this.isState !== 'detail') {
return true
}else {
return false;
}
},
},
methods: {
/**
* 上传文件前触发
* @param {Object} file 文件数据
*/
beforeUpload(file) {
// 文件名校验
if(file.name.substring(0,file.name.indexOf(".")).length>50){
this.$message.error('上传文件名字不得超过50字');
return false;
}
// 文件类型校验
let fileExt = file.name.slice(file.name.lastIndexOf('.')+1);
if(this.accept.indexOf(fileExt) === -1) {
this.$message.error('禁止上传非法的文件类型');
return false;
}
// 文件大小校验
let fileSize = file.size / 1024 / 1024;
if(fileSize > this.size) {
this.$message.error('只允许上传' + this.size + 'M一下的文件');
return false;
}
return true;
},
/**
* 上传文件改变触发
* @param {Object} info 文件信息
* */
handleChange(info) {
let fileList = [...info.fileList].filter(item => {
return item.status !== undefined
});
if (this.limit !== 0) {
fileList = fileList.slice(-this.limit);
}
fileList = fileList.map(file => {
if (file.response) {
file.url = file.response.url;
}
return file;
});
this.$emit('update:fileList', fileList);
},
/**
* 文件预览回调
* @param {Object} file 文件
* */
handlePreview(file) {
console.log("触发文件预览");
},
/**
* 文件下载回调
* @param {Object} file 文件
* */
handleDownload(file) {
let fileName = file.name,
filePathId = file.response.data.data[0].fileId;
const a = document.createElement("a");
a.download = `${fileName}`;
a.href = "/api/download/" + filePathId;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},
}
}
</script>
<style lang="less" scoped>
.uploadHide {
& /deep/ .ant-upload.ant-upload-drag {
display: none;
}
}
.upload-accept {
font-size: 1em;
color: gray;
}
</style>