步骤

  • 安装依赖包 npm install --save lrz
  • main.js里引入 import lrz from 'lrz'
  • 封装 compress函数
  • 封装上传组件 upload-image
  • 在 vue 文件中 使用

封装 compress函数

// eslint-disable

/** @format */
// base64编码转File
export function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
} // main function.
export function compress(file, fileList, that, reference) {
if (file.status != 'ready') {
return;
}
let index = reference.uploadFiles.indexOf(file); // jpg/jpeg/bmp/gif/png
let isJPG =
file.raw.type === 'image/jpg' ||
file.raw.type === 'image/jpeg' ||
file.raw.type === 'image/png' ||
file.raw.type === 'image/gif' ||
file.raw.type === 'image/bmp' const isLt20M = file.size / 1024 / 1024 < 20;
if (!isJPG) {
that.$message.error('不支持的格式,请上传jpg/jpeg/bmp/gif/png格式的图片!');
fileList.splice(fileList.indexOf(file), 1);
return;
}
if (!isLt20M) {
that.$message.error('上传图片大小不能超过 20MB!');
fileList.splice(fileList.indexOf(file), 1);
return;
}
if (isJPG & isLt20M) {
if (isLt2M(file)) {
// pdf不压缩
submit(reference, file);
} else {
let options = {};
lrz(file.raw, options)
.then(rst => {
let tempFile = dataURLtoFile(rst.base64, rst.origin.name);
tempFile.uid = rst.origin.uid;
reference.uploadFiles[index].raw = tempFile;
reference.uploadFiles[index].size = rst.fileLen;
})
.catch(function (error) {
// 失败时执行
if (error) {
// IE报错
if (error.name == 'TypeError' && error.message == '对象不支持此操作') {
that.$message.error('当前浏览器不支持上传大于2M的文件,请更换浏览器!');
}
// 图片格式问题
else if ((error + '').indexOf('加载图片文件失败') > -1) {
that.$message.error('系统未能识别当前上传图片,请更换!');
}
}
fileList.splice(fileList.indexOf(file), 1);
})
.always(function () {
//不管成功或失败都会执行
submit(reference, file);
});
}
}
}
// 判断文件大小是否小于2M
function isLt2M(file) {
if (file.raw.type === 'application/pdf') {
return true;
} else {
return file.size / 1024 / 1024 < 2;
}
} function submit(reference, file) {
let submitFlag = true;
if (reference.multiple) {
for (let item of reference.uploadFiles) {
if (item.status != 'ready') {
continue;
}
if (!isLt2M(item)) {
submitFlag = false;
break;
} else {
submitFlag = true;
}
}
} else {
if (!isLt2M(file)) {
submitFlag = false;
} else {
submitFlag = true;
}
}
if (submitFlag) {
reference.submit();
return;
}
}

封装上传组件upload-image

<template>
<div class="upload-component-container">
<div class="upload-section">
<!-- 上传主体 -->
<el-row>
<el-upload
ref="imageUploadRef"
:headers="token"
:action="uploadUrl"
:auto-upload="false"
list-type="picture-card"
:file-list="imageList"
:on-change="resize"
:on-remove="handleRemove"
:on-preview="handlePreview"
:on-success="handleSuccess"
:on-error="handleError"
:on-exceed="handleExceed"
:on-progress="handleProgress"
:class="imageList.length >= maxCount ? 'uploaded-none':''"
:limit="maxCount"
>
<div class="icon-container" v-loading="loading">
<i class="el-icon-plus upload-icon"></i>
</div>
</el-upload>
</el-row>
<!-- 上传描述 -->
<el-row v-if="needDesc">
<div class="upload-text-desc" :style="descStyle">{{uploadDesc}}</div>
</el-row>
</div>
<!-- 查看图片 -->
<el-dialog
width="50%"
:modal="modal"
@close="imageVisible=false"
:modal-append-to-body="false"
:visible.sync="imageVisible"
>
<img width="100%" :src="dialogImageUrl" alt />
</el-dialog>
</div>
</template>
<script>
import { getBaseUrl, uuid as getUUId } from '@/utils/basic/' // 引入项目的api前缀
import { getToken } from '@/utils/browser' // 引入token
import { compress } from '@/utils/image/compress' // 引入上一步封装的压缩函数
import lodash from 'lodash'
export default {
name: 'UploadImage',
props: {
modal: { type: Boolean, default: () => { false } },
maxCount: { type: Number, required: true },
uploadDesc: { type: String },
initShowImages: { type: [Array, String], required: true },
singleFile: { type: Boolean, default: false },
needDesc: { type: Boolean, default: true },
handleChange: { type: Function, required: true },
descStyle: { type: Object, default: () => { null } }
},
data() {
return {
uploadUrl: getBaseUrl() + '/api/base/uploadImg',
token: { Authorization: getToken(), 'X-Trace-ID': getUUId() },
imageList: [],
loading: false,
imageVisible: false,
dialogImageUrl: ''
}
},
methods: {
// 启用压缩
resize(file, fileList) {
compress(file, fileList, this, this.$refs.imageUploadRef)
},
// 上传成功
handleSuccess(res, f, fList) {
if (res.status === 1 && res.result.length > 0) {
if (res.result[0].url) {
this.imageList.push({
url: res.result[0].url,
// 兼容saas的初始 attachmentUrl 属性
attachmentUrl: res.result[0].url //
})
} else {
this.imageList.push({
url: fList[0].url,
// 兼容saas的初始 attachmentUrl 属性
attachmentUrl: fList[0].url //
})
}
}
// 根据接收类型将结果发送到父组件
if (this.singleFile == true) {
this.handleChange(this.imageList[0].url)
} else {
this.handleChange(this.imageList)
}
this.loading = false
},
// 删除事件
handleRemove(res) {
this.imageList = lodash.filter(this.imageList, item => {
if (res.response) {
return item.url !== res.response.result[0].url
} else {
return item.url !== res.url
}
})
// 根据接收类型将结果发送到父组件 => 单个文件
if (this.singleFile == true) {
this.handleChange('')
} else {
this.handleChange(this.imageList)
}
this.$forceUpdate()
}, // 最大数
handleExceed() {
this.$message({ type: 'warning', message: `最多上传${this.maxCount}张图片` })
},
// 上传错误
handleError(err, file, fileList) {
this.$message({ message: err.data.msg, type: 'error' })
},
// 查看图片
handlePreview(file) {
this.dialogImageUrl = file.url
this.imageVisible = true
},
handleProgress() {
this.loading = true
}
},
mounted() {
// case: string(logo)
if (this.singleFile == true) {
// 非空值
if (this.initShowImages) {
this.imageList.push({ url: this.initShowImages })
} else {
this.imageList = []
}
} else {
// 列表文件
this.imageList = this.initShowImages
}
},
watch: {
initShowImages(val) {
// case: string(logo)
if (this.singleFile == true) {
// 非空值
if (val) {
this.imageList = [{ url: val }]
} else {
this.imageList = []
}
} else {
// 列表文件
this.imageList = val
}
}
}
}
</script>
<style lang="scss">
.upload-component-container {
.upload-section {
background: #ffffff;
border-radius: 4px;
padding-top: 2px;
.uploaded-none {
.el-upload--picture-card {
display: none;
}
}
.el-upload-list--picture-card .el-upload-list__item {
width: 60px;
height: 60px;
}
.el-upload--picture-card {
width: 60px;
height: 60px;
line-height: 125px;
i {
font-size: 20px !important;
}
}
.icon-container {
line-height: 2.5em;
padding-top: 12px;
}
.el-icon-plus:before {
// background: rgb(77, 227, 193);
color: #000;
border-radius: 12px;
}
}
.upload-text-desc {
font-size: 12px;
color: #939393;
margin-top: 4px;
margin-bottom: 5px;
}
}
</style>

在 vue 文件中使用

<template>
<div class="contract-other-edit-container">
<el-row>
<el-col :span="12">
<upload-image
:modal="false"
:maxCount="5"
uploadDesc="格式要求:支持jpg/jpeg/bmp/gif/png格式图片,大小不超过20MB,多上传5张图片."
:handleChange="handleUploadImage"
:initShowImages="imageList"
/>
</el-col>
</el-row>
</div>
</template> <script>
import UploadImage from '@/components/element-ui/upload/image' // 组件的位置 export default {
name: 'other-edit',
components: { UploadImage },
data() {
return {
imageList: []
}
},
methods: {
handleUploadImage(files) {
this.imageList = files
}
}
}
</script>

Vue 图片压缩上传: element-ui + lrz的更多相关文章

  1. 基于vue + axios + lrz.js 微信端图片压缩上传

    业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...

  2. 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)

    涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...

  3. Html5+asp.net mvc 图片压缩上传

    在做图片上传时,大图片如果没有压缩直接上传时间会非常长,因为有的图片太大,传到服务器上再压缩太慢了,而且损耗流量. 思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法 ...

  4. 纯原生js移动端图片压缩上传插件

    前段时间,同事又来咨询一个问题了,说手机端动不动拍照就好几M高清大图,上传服务器太慢,问问我有没有可以压缩图片并上传的js插件,当然手头上没有,别慌,我去网上搜一搜. 结果呢,呵呵...诶~又全是基于 ...

  5. springMVC多图片压缩上传的实现

    首先需要在配置文件中添加配置: <!--配置文件的视图解析器,用于文件上传,其中ID是固定的:multipartResolver--> <bean id="multipar ...

  6. 基于H5+ API手机相册图片压缩上传

    // 母函数 function App(){} /** * 图片压缩,默认同比例压缩 * @param {Object} path * pc端传入的路径可以为相对路径,但是在移动端上必须传入的路径是照 ...

  7. 分享图片压缩上传demo,可以选择一张或多张图片也可以拍摄照片

    2016-08-05更新: 下方的代码是比较OLD的了,是通过js进行图片的剪切 旋转 再生成,效率较低. 后来又整合了一个利用native.js本地接口的压缩代码 ,链接在这 .页面中有详细的说明, ...

  8. js 图片压缩上传(base64位)以及上传类型分类

    一.input file上传类型 1.指明只需要图片 <input type="file" accept='image/*'> 2.指明需要多张图片 <input ...

  9. Vue directive自定义指令+canvas实现H5图片压缩上传-Base64格式

    前言 最近优化项目-手机拍照图片太大,回显速度比较慢,使用了vue的自定义指令实现H5压缩上传base64格式的图片 canvas自定义指令 Vue.directive("canvas&qu ...

随机推荐

  1. 【软件安装】在 CentOS 7(Linux)上部署流媒体服务(Tengine、ffmpeg、Centos 7、nginx-http-flv-module、OBS)

    Centos7+Tengine+Nginx-http-flv-module+ffmpeg+OBS搭建流媒体服务器 一.需求和背景 视频直播是基于领先的内容接入.分发网络和大规模分布式实时转码技术打造的 ...

  2. 《python编程从入门到实践》2.3字符串

    书籍<python编程从入门到实践> 2.3字符串 知识模块 print()函数,函数名称突出为蓝色,输出括号内的变量或者字符创. 变量名的命名:尽量小写字母加下划线并且具有良好的描述性, ...

  3. 题解 洛谷 P3298 【[SDOI2013]泉】

    考虑到年份数很小,只有 \(6\),所以可以 \(2^6\) 来枚举子集,确定流量指数对应相同的位置,然后通过哈希和排序来计算相同的方案数. 但是这样计算出的是大于等于子集元素个数的方案数,所以还需要 ...

  4. 10个Vue开发技巧助力成为更好的工程师·二

    优雅更新props 更新 prop 在业务中是很常见的需求,但在子组件中不允许直接修改 prop,因为这种做法不符合单向数据流的原则,在开发模式下还会报出警告.因此大多数人会通过 $emit 触发自定 ...

  5. 【管理员已阻止你运行此应用】windows defender图标打叉,无法打开mmc.exe解决办法

    今天开机遇到一个奇怪的问题,发现windows defender图标上面打了个×: 打开按照系统提示需要restart服务,但是无法重启服务,会出现错误,然后尝试手动重启服务,准备打开管理控制台mmc ...

  6. goroutine间的同步&协作

    Go语言中的同步工具 基础概念 竞态条件(race condition) 一份数据被多个线程共享,可能会产生争用和冲突的情况.这种情况被称为竞态条件,竞态条件会破坏共享数据的一致性,影响一些线程中代码 ...

  7. iPhone截长图的方法

    iPhone手机暂没有长图截取功能,所以我们只能通过别的方式进行长图截取. (2020年4月10日更新) ios13目前可以截长图了,不过只能在Safari中进行长图截取,而且存储形式为pdf格式,下 ...

  8. python的常用模块

    一.random随机数模块 使用随机数模块需要导入随机数模块import random 1.random.random() 生成[0,1)之间的随机小数 2.random.randint(a,b) 生 ...

  9. ImportError: /lib64/libm.so.6: version `GLIBC_2.23' not found (required by /usr/local/python37/lib/python3.7/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so)

    一 问题背景 这个错误的出现往往与我前面的一篇文章 ImportError: /lib64/libm.so.6: version `CXXAB_1.3.8.' not found (required ...

  10. 恕我直言,我也是才知道ElasticSearch条件更新是这么玩的

    背景 ElasticSearch 的使用度越来越普及了,很多公司都在使用.有做日志搜索的,有做商品搜索的,有做订单搜索的. 大部分使用场景都是通过程序定期去导入数据到 ElasticSearch 中, ...