前端使用Compressor.js实现图片压缩上传
Compressor.js官方文档
安装
1
| npm install compressorjs
|
使用
在使用ElementUI或者其他UI框架的上传组件时,都会有上传之前的钩子函数,在这个函数中可以拿到原始file,这里我用VantUI的上传做演示
1 2 3 4 5 6 7
| <van-uploader :max-count="prop.limit" v-model="state.fileList" :after-read="afterRead" :before-read="beforeRead" @delete="deleteFile" />
|
afterRead函数时上传之前的钩子,可以获取到file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| <template> <div> <van-uploader :max-count="prop.limit" v-model="state.fileList" :after-read="afterRead" :before-read="beforeRead" @delete="deleteFile" /> </div> </template> <script setup> import { reactive, defineEmits, defineProps, watch } from 'vue' import { FileUploadFun } from '@/api/index.js' import { useCustomFieldValue } from '@vant/use' import { Toast } from 'vant' import Compressor from 'compressorjs'
const prop = defineProps({ url: { type: String, default: '', }, limit: { type: Number, default: 5, }, }) const emit = defineEmits(['onSuccess']) const state = reactive({ fileList: [], })
watch( () => prop.url, () => { if (prop.url) { state.fileList = [] prop.url.split(',').forEach((item) => { state.fileList.push({ url: item, }) }) } } )
const beforeRead = (file) => { return new Promise((resolve, reject) => { new Compressor(file, { quality: 0.2, success(result) { let newFile = new File([result], file.name, { type: file.type }) resolve(newFile) }, error(err) { reject(err) }, }) }) }
const afterRead = (file) => { file.status = 'uploading' file.message = '上传中...'
FileUploadFun(file.file) .then((res) => { file.status = 'done' file.message = '上传成功' let urls = state.fileList.map((i) => i.url) urls.pop() urls.push(res.data.url) emit('onSuccess', urls.join(',')) }) .catch(() => { state.fileList.pop() file.status = 'done' Toast('上传失败') }) }
const deleteFile = () => { emit('onSuccess', state.fileList.map((i) => i.url).join(',')) }
useCustomFieldValue(() => state.fileList.map((item) => item.url).join(',')) </script>
|
示例
Quality |
原始大小 |
压缩后大小 |
压缩比 |
Description |
0 |
2.12 MB |
114.61 KB |
94.72% |
- |
0.2 |
2.12 MB |
349.57 KB |
83.90% |
- |
0.4 |
2.12 MB |
517.10 KB |
76.18% |
- |
0.6 |
2.12 MB |
694.99 KB |
67.99% |
推荐 |
0.8 |
2.12 MB |
1.14 MB |
46.41% |
推荐 |
1 |
2.12 MB |
2.12 MB |
0% |
不推荐 |
NaN |
2.12 MB |
2.01 MB |
5.02% |
- |
测试效果

可以看到压缩前的图片大小3.29M,压缩后342KB
下面是前后的图片对比
原图

压缩后的图
