需求
这样一个普通是上传图片的框。最多可以上传8张图。
验证要求:
1.必填
2.不能超过5M (定义变量写成isLt1000KB 了。。。大家忽略)
3.格式必须是图片格式
4.验证错误提示‘第几张图片XX错误’
如何实现呢?
一、原理说明
- 对于一张图片,验证基本原理,挺简单
const isLt1000KB = v.size / 1024 < 5000; //5M
const isPic =
/.*\.(bmp|jpg|png|tif|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF|webp|jpeg)/i.test(
v.name
);
- 但是对于多张图片呢?
我于是定义了一个map
记录八张图片的情况。这样你想要显示那张图片的哪个类型验证你取map
里面的值就可以了。
const img2_err_msg = ref(
new Map([
[0, { isPic: true, isLt1000KB: true, file: null }],
[1, { isPic: true, isLt1000KB: true, file: null }],
[2, { isPic: true, isLt1000KB: true, file: null }],
[3, { isPic: true, isLt1000KB: true, file: null }],
[4, { isPic: true, isLt1000KB: true, file: null }],
[5, { isPic: true, isLt1000KB: true, file: null }],
[6, { isPic: true, isLt1000KB: true, file: null }],
[7, { isPic: true, isLt1000KB: true, file: null }],
])
);
二、html 结构
<el-form
ref="refShopForm01"
:model="shopInfo"
:rules="rules"
...
>
...(中间其他代码省略)
...
<el-form-item class="m-32" label="室内图(最多8张)" prop="img2">
<el-upload
v-model:file-list="shopInfo.img2"
action="#"
list-type="picture-card"
:auto-upload="false"
:on-preview="handlePictureCardPreview"
:limit="8"
:on-remove="handleRemove2"
>
<el-icon><Plus /></el-icon>
</el-upload>
</el-form-item>
...(其他代码省略)
三、js 结构
const refShopForm01 = ref<FormInstance>();
//记录多张图片的不符合要求的问题
const img2_err_msg = ref(
new Map([
[0, { isPic: true, isLt1000KB: true, file: null }],
[1, { isPic: true, isLt1000KB: true, file: null }],
[2, { isPic: true, isLt1000KB: true, file: null }],
[3, { isPic: true, isLt1000KB: true, file: null }],
[4, { isPic: true, isLt1000KB: true, file: null }],
[5, { isPic: true, isLt1000KB: true, file: null }],
[6, { isPic: true, isLt1000KB: true, file: null }],
[7, { isPic: true, isLt1000KB: true, file: null }],
])
);
const shopInfo = reactive({
//室内图--最多8张
img2: [] as UploadUserFile[],
});
// 验证规则
const rules = reactive<FormRules>({
img2: [
{
required: true,
message: "请选择图片",
trigger: "blur",
},
{ validator: validatePic2, trigger: "blur" },
],
});
// 验证多张图片
function validatePic2(rule: any, value: UploadUserFile[], callback: any) {
let n = value.length;
if (n == 0) {
callback(new Error("请选择图片"));
} else {
_very(value[n - 1], n - 1);
}
function _very(v: UploadUserFile, i: number) {
const isLt1000KB = v.size / 1024 < 5000; //5M
const isPic =
/.*\.(bmp|jpg|png|tif|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF|webp|jpeg)/i.test(
v.name
);
img2_err_msg.value.set(i, { isPic, isLt1000KB, file: v });
if (!isPic) {
callback(new Error(`第${i + 1}张-格式不支持`));
}
if (!isLt1000KB) {
callback(new Error(`第${i + 1}张-图片超过5M`));
}
if (isPic && isLt1000KB) {
let _msg = "";
img2_err_msg.value.forEach((item, index) => {
if (!item.isPic) {
_msg = `第${index + 1}张-格式不支持`;
return;
}
if (!item.isLt1000KB) {
_msg = `第${index + 1}张-图片超过5M`;
return;
}
});
if (_msg.length > 0) {
callback(_msg);
} else {
callback();
}
}
}
}
async function handleRemove2(
uploadFile: UploadFile,
uploadFiles: UploadUserFile[]
) {
let index = 7;
img2_err_msg.value.forEach((item, ii) => {
if (item.file == uploadFile) {
index = ii;
}
});
for (let ii = index; ii < 7; ii++) {
let _old = img2_err_msg.value.get(ii + 1);
img2_err_msg.value.set(ii, _old);
}
img2_err_msg.value.set(7, { isPic: true, isLt1000KB: true, file: null });
await refShopForm01.value?.validateField("img2");
}
js 函数解释
`_very` 验证某张图片是否通过验证
`handleRemove2` 在移除图片的时候更新验证信息map,并重新验证
效果截图
- 正常图片
- 第二张超过5m
(.… 大概了,自己实现后自己看,有什么疑问友友们留言吧)