UploadImg 图片上传
更新: 2025/3/26 字数: 0 字 时长: 0 分钟
说明
原生input组件的二次封装,上传前会有拍照或者相册选项,并在上传过程中展示预览图和上传进度。上传图片至服务器的接口逻辑,该步骤需要自行实现。更多基础功能详见 input type="file"。
基本使用
选择图片
点击组件,会弹出拍照或者相册选择框。每次只能选择上传一张图片。
html
<upload-img
v-model:file-list="fileList"
:before-read="beforeRead"
:after-read="afterRead"
@delete="deleteFile"
/>
上传图片之前校验
使用 before-read
属性,可以自定义上传前的校验。
ts
const beforeRead = (file) => {
if (file.type !== "image/jpeg") {
showToast("请上传 jpg 格式图片");
return false;
}
if (file.size > 1024 * 1024 * 5) {
showToast("请上传不超过5Mb的图片");
return false;
}
return true;
};
上传图片之后处理
使用 after-read
属性,可以自定义上传后的处理。通过修改file
的status,可以控制图片上传后的状态。
ts
// 压缩大小
const compressImg = (base64, scale, fileName) => {
// 处理缩放,转换格式
// 用canvas来压缩
const img = new Image();
img.src = base64;
return new Promise((resolve, reject) => {
img.onload = async () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.setAttribute("width", String(img.width * scale));
canvas.setAttribute("height", String(img.height * scale));
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
// 转成base64 文件
base64 = canvas.toDataURL("image/jpeg", 0.8); // 0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值
const arr = base64.split(",");
const mime = arr[0].match(/:(.*?);/)[1];
const bytes = atob(arr[1]);
const bytesLength = bytes.length;
const u8arr = new Uint8Array(bytesLength);
for (let i = 0; i < bytes.length; i++) {
u8arr[i] = bytes.charCodeAt(i);
}
const file = new File([u8arr], fileName, { type: mime });
resolve(file);
};
img.onerror = (error) => {
reject(error);
};
});
};
// 开始上传图片
const afterRead = async (file) => {
// 压缩图片,大于2Mb就压缩
let imgFile = null;
if (file.file.size / 1024 / 1024 > 2) {
imgFile = await compressImg(file.content, scale, file.file.name);
} else {
imgFile = file.file;
}
// file.status = 'uploading'
// file.message = '上传中'
// console.log(imgFile, '压缩后的图片文件获取');
const formData = new FormData();
formData.append("files", imgFile);
// 下面是接口处理逻辑
// const res = await fileUpload(formData, config)
// if (res && res.code === 0) {
// const datas = res.list[0]
// file.status = 'done'
// fileArr.value.push(datas)
// }
// else {
// fileList.value[fileList.value.length - 1].status = 'failed'
// }
// fileList.value[fileList.value.length - 1].status = 'done'
};
API
传参配置
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
v-model:file-list | 图片列表 | Array | [] |
fileType | 文件类型 | String | image/jpeg |
maxCount | 最大上传数量 | Number | 3 |
limit | 每次多选相册时最多选择的图片数量,最小值为1 | Number | 1 |
previewSize | 预览图片的尺寸,如 100px,auto 等 | String|Number | 80px |
previewFullImage | 是否在点击预览图后展示全屏图片预览 | Boolean | true |
tips | 提示文字 | String | - |
uploadText | 上传按钮的文字 | String | - |
uploadIcon | 上传按钮的图标 | String | photograph |
disabled | 是否禁用上传按钮 | Boolean | false |
showUpload | 是否显示上传区域 | Boolean | true |
showFileList | 是否显示已上传文件列表 | Boolean | true |
before-read | 上传前的钩子,返回 false 可终止上传 | Function(file) | - |
after-read | 上传后的钩子 | Function(file) | - |
before-delete | 删除文件前的钩子,返回 false 可终止文件读取 | Function(file) | - |
事件
事件名 | 说明 | 回调参数 |
---|---|---|
delete | 删除图片的钩子 | Function(file) |