步骤

  • 安装依赖包 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. Windows File Recovery - 微软官方文件恢复工具

    假如你不小心误删除了文件或因各种意外情况丢失数据后,你可以通过 微软这款工具 这个工具来尝试恢复它们.WinFR 工具支持读取本机硬盘.移动硬盘.U 盘,或者连接相机.手机.使用读卡器来恢复 SD.T ...

  2. 发布一个自己做的图片转Base64的软件,Markdown写文章时能用到

    markdownpic 介绍 Markdown编辑时图片生成base64 软件架构 使用了.netcore winform框架 安装教程 直接运行即可 使用说明 拖拽图片文件 双击选择文件 复制粘贴图 ...

  3. 05 ES6模块化规范基础详解

    ES6模块规范 1.1 ES6规范说明 历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来.其他语言都有这项功能,比如 Ru ...

  4. H5移动端,ios从后台返回到app,页面会白一下

    visibilitychange事件可以检查从后台返回事件,然后通过添加div,强制浏览器刷新页面 var divEle = document.createElement("DIV" ...

  5. DJANGO-天天生鲜项目从0到1-007-首页静态化与缓存

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  6. python线程,进程,队列和缓存

    一.线程 threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 创建线程的两种方式1.threading.Thread import threading def f1(arg): ...

  7. 《精通Python网络爬虫》|百度网盘免费下载|Python爬虫实战

    <精通Python网络爬虫>|百度网盘免费下载|Python爬虫实战 提取码:7wr5 内容简介 为什么写这本书 网络爬虫其实很早就出现了,最开始网络爬虫主要应用在各种搜索引擎中.在搜索引 ...

  8. P1359租用游艇(dp+dfs)

    好久真的是好久没有做dp的问题了(QWQ)(我有学过这玩意???) 诶,人生呐! 今天来一个动归- 顺便可以回顾一下dfs. 这个题我觉得审题也非常重要 小可爱dp: #include <bit ...

  9. maven 一些高级用法命令

    发布本地jar到私服 命令 mvn deploy:deploy-file -Dmaven.test.skip=true -Dfile=D:\Downloads\OJDBC-Full\ojdbc6.ja ...

  10. Django学习路16_获取学生所在的班级名

    在 urls.py 中先导入getgrades from django.conf.urls import url from app5 import views urlpatterns = [ url( ...