vue+elementUI上传图片笔记总结
有裁剪框
上传图片组件:
class="avatar-uploader" :before-upload="beforeUpload" :http-request="httpRequest" :on-success="handleAvatarSuccess" :show-file-list="false"> //有图片时显示上传图片 //无图片时显示默认图标 //修改和新增转态显示
//删除
裁剪弹框:
ref="cropper" style="height: 400px" //截图框移动 :can-move="option.canMove" //截图框拖动 :can-move-box="option.canMoveBox" :fixed-box="option.fixedBox" :img="cropOption.image" :fixed="cropOption.fixed" :height="cropOption.height" :outputSize="cropOption.size" :outputType="cropOption.type" :autoCrop="cropOption.autoCrop" :autoCropWidth="cropOption.autoCropWidth" :autoCropHeight="cropOption.autoCropHeight" :original="cropOption.original">
//点击确定上传图片
上传前校验:
beforeUpload(file) {
// 上传前校验
const isJPG = ['image/jpeg', 'image/jpg', 'image/png'].includes(file.type);
const isLt500k = file.size / 1024 / 1024 < 0.5;
if (!isJPG) {
this.$message.warning('外部图标只能是 jpg / png 格式');
return false;
}
if (!isLt500k) {
this.$message.warning('外部图标大小不能超过 500k');
return false;
}
this.cropOption.image = window.URL.createObjectURL(file);
// 打开裁剪框
this.showImageCropper = true;
裁剪并上传图片:
// 裁剪并上传图片
imageCropper() {
//获取裁剪框的图片信息
this.$refs.cropper.getCropBlob(data => {
const file = new File([data], 'icon.png', {
type: data.type,
lastModified: Date.now(),
});
//格式化图片
const formData = new FormData();
//添加属性
formData.append('file', file, file.name);
const loading = this.$loading({
lock: true,
text: '图片上传中, 请稍后...',
spinner: 'el-icon-loading',
});
//请求接口
axios
.post('/api/spang-system/oss/endpoint/put-file', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
})
.then(res => {
loading.close();
if (res.status && res.status === 200) {
this.$set(this.form, 'icon', res.data.data.link);
this.showImageCropper = false;
}
})
.catch(e => {
loading.close();
this.$message.error(`图片上传失败!${JSON.stringify(e)}`);
})
.finally(() => {
loading.close();
});
});
},
取消裁剪框并验证尺寸
上传时获取图片并处理
因为不需要裁剪框,先注释掉裁剪框代码,之前是通过裁剪框的确定按钮上传图片的,现在没有裁剪框,要怎么上传图片呢?在上传前的较校验部分调用上传图片的函数,要注意的是,之前的上传操作中的图片是通过裁剪弹框组件自带属性来获取,现在没有裁剪框,要怎么拿到图片并上传呢? 通过beforeUpload(file)参数file,在beforeUpload(file)中调用上传函数this.imageCropper(file)传入参数file,上传时就可以获取到图片信息并上传了。 具体实现中会有点小问题,裁剪上传通过如下:
imageCropper() {
this.$refs.cropper.getCropBlob(data => {
const file = new File([data], 'icon.png', {
type: data.type,
lastModified: Date.now(),
});
猜测:cropper和getCropBlob要同时使用,单独使用getCropBlob并不能拿到东西??? 总之,对file的处理参考了网上的简单方法,直接去掉imageCropper部分,file参数本来就传递数据,不用再定义变量来接收了,直接进行如下操作:
const formData = new FormData();
formData.append('file', file, file.name);
这样就可以成功上传了 不符合尺寸时会提示,不会上传
添加尺寸校验
代码如下:
const isSize = new Promise(function (resolve, reject) {
const width = 82; // 限制图片尺寸
const height = 82;
const URL = window.URL || window.webkitURL;
const img = new Image();
img.onload = function () {
const valid = img.width === width && img.height === height;
valid ? resolve() : reject();
};
img.src = URL.createObjectURL(file);
}).then(
//valid为true时调用resolve()
() => {
return true;
},
//valid为false时调用reject()
() => {
this.$message.warning('外部图标尺寸应为 82 * 82');
return false;
}
);
isSize.then(res => {
console.log('res', res);
if (isJPG && isLt500k && res) {
this.imageCropper(file);
}
});
console.log(isSize);
需要注意的是, isSize返回的是promise对象,valid为true时返回值是true,valid为false时返回值是false,如果直接判断isSize来调用this.imageCropper(file),判断不生效,因为返回的不是空对象,都会执行上传操作,就会造成不符合尺寸的图片会提示尺寸不符合,但仍会成功上传 所以通过then方法来取到我们所需要的PromiseResult值,PromiseResult就是返回的Promise对象返回的布尔值,如下:
isSize.then(res => {
console.log('res', res);
if (isJPG && isLt500k && res) {
this.imageCropper(file);
}
});
},
在then函数中,拿到 PromiseResult的值后直接进行上传判断即可。 最终的上传和校验代码如下:
//上传图片
imageCropper(file) {
const formData = new FormData();
formData.append('file', file, file.name);
const loading = this.$loading({
lock: true,
text: '图片上传中, 请稍后...',
spinner: 'el-icon-loading',
});
axios
.post('/api/spang-system/oss/endpoint/put-file', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
})
.then(res => {
loading.close();
if (res.status && res.status === 200) {
this.$set(this.form, 'icon', res.data.data.link);
this.showImageCropper = false;
}
})
.catch(e => {
loading.close();
this.$message.error(`图片上传失败!${JSON.stringify(e)}`);
})
.finally(() => {
loading.close();
});
},
// 图片上传前校验
beforeUpload(file) {
const isJPG = ['image/jpeg', 'image/jpg', 'image/png'].includes(file.type);
const isLt500k = file.size / 1024 / 1024 < 0.5;
if (!isJPG) {
this.$message.warning('外部图标只能是 jpg / png 格式');
return false;
}
if (!isLt500k) {
this.$message.warning('外部图标大小不能超过 500k');
return false;
}
const isSize = new Promise(function (resolve, reject) {
const width = 82; // 限制图片尺寸为
const height = 82;
const URL = window.URL || window.webkitURL;
const img = new Image();
img.onload = function () {
const valid = img.width === width && img.height === height;
valid ? resolve() : reject();
};
img.src = URL.createObjectURL(file);
}).then(
() => {
return true;
},
() => {
this.$message.warning('外部图标尺寸应为 82 * 82');
return false;
}
);
console.log('isSize', isSize);
isSize.then(res => {
console.log('res', res);
if (isJPG && isLt500k && res) {
this.imageCropper(file);
}
});
},
好文阅读
发表评论