vue+elementUI上传图片笔记总结

有裁剪框

上传图片组件:

裁剪弹框:

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);

}

});

},

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: