主要功能:限制图片张数、图片大小压缩、同时上传多张、上传后可编辑删除、上传中和上传失败状态显示。
使用配置:使用vantUI、axios请求经过封装、安装image-compressor.js图片压缩
步骤:
- 安装image-compressor.js
npm install image-compressor.js //注意是image-compressor.js不是image-compressor
- 创建一个VUE组件,文件名可以为updatefile
<template>
<div class="updatefile">
<div class="fileCon">
<div class="list">
<div v-for="(item,index) in list" :key="index">
<img class="close" src="../assets/delete.png" @click="close(index)">
<img :src="item" />
</div>
<div class="add" v-show="maxStatus" @click="chooseType">
<img class="add-image" src="../assets/add.png">
</div>
</div>
</div>
<input id="upload_file" type="file" class="file-input" accept="image/png,image/jpeg,image/jpg" :multiple="multiple" @change="inputChange" style="display: none" />
</div>
</template>
<script>
import { Toast } from 'vant'
import ImageCompressor from 'image-compressor.js'
import checkImgFileSize from '@/utils/checkImgFileSize.js'
export default {
name: 'updatefile',
data() {
return {
maxStatus: true,
}
},
props: {
//是否支持多选
multiple: {
type: Boolean,
default: true,
},
//最多上传几张
max: {
type: Number,
default: 3,
},
//编辑反显使用
list: {
type: Array,
default() {
return []
},
},
},
created() {
this.maxStatus = this.list.length !== this.max
},
methods: {
chooseType() {
document.getElementById('upload_file').click()
},
close(index) {
this.list.splice(index, 1)
this.maxStatus = this.list.length !== this.max
},
async inputChange(e) {
let files = e.target.files
let len = this.list.length + files.length
if (len > this.max) {
document.getElementById('upload_file').value = ''
Toast(`最多允许上传${this.max}张`)
return
}
let uploadAll = [].slice.call(files, 0).map(this.upload)
// 使用object.values(files),测试安卓存在兼容性问题,替换为[].slice.call(files ,0)
Toast.loading({
// 上传中效果,可自行替换。
text: '上传中...',
spinnerType: 'fading-circle',
})
let result = await Promise.all(uploadAll)
console.log('result:' + result)
document.getElementById('upload_file').value = ''
Toast.clear()
},
upload(file) {
// console.log('file1: ', file)
return new Promise(async resolve => {
if (checkImgFileSize(file)) {
const that = this
const imageCompressor = new ImageCompressor(file, {
// 图片压缩的质量,可改
quality: 0.2,
success(fileRes) {
that.uploadFile(fileRes, resolve)
},
})
console.log(imageCompressor)
} else {
this.uploadFile(file, resolve)
}
})
},
// 调用接口上传图片
uploadFile(file, resolve) {
// console.log('file2: ', file)
let form = new FormData()
form.append('uploadFileName', file)
// form.append('***') //根据上传入参添加参数
this.$instance
.post('v1/admin/upload/file', form)
.then(result => {
if (result.data.data !== undefined) {
if (result.data.code !== 0) {
// 失败处理
Toast(`图片上传失败`)
resolve(result)
// return
} else {
this.list.push(result.data.data)
// console.log('this.list: ', this.list)
if (this.list.length === this.max) {
this.maxStatus = false
}
resolve(result)
}
} else {
// 失败处理
Toast(`图片上传失败`)
}
})
.catch(error => {
Toast(`图片上传失败`)
console.log('error: ', error)
})
},
},
}
</script>
<style lang="scss" scoped>
.updatefile {
.fileCon {
width: 100%;
min-height: 76px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
.list {
width: 100%;
min-height: 76px;
display: flex;
flex-wrap: wrap;
align-items: center;
& > div {
width: 54px;
height: 54px;
margin: 10px 10px 10px 0;
position: relative;
background: #ccc;
& > img {
width: 100%;
height: 100%;
}
.close {
width: 15px;
height: 15px;
background-color: #fff;
border-radius: 50%;
background-image: url(../assets/delete.png);
background-size: 100%;
position: absolute;
top: -4px;
right: -4px;
}
}
}
}
.add {
width: 54px;
height: 54px;
background-color: #ccc;
.add-image {
width: 20px !important;
height: 20px !important;
position: relative;
top: 15px;
left: 50%;
transform: translate(-50%);
}
}
}
</style>
ps:从父级页面传入相应的值到props里面
- 引入checkImgFileSize.js,该文件表示图片超过1M就进行压缩
export default (file, maxSize = 1) => {
// 转为 M
const size = file.size
return size >= maxSize * 1024 * 1024
}