大致步骤
- 1 图片分块
- 2 分块的图片 用formdata 保存在发后台
代码实现
<template>
<el-upload
class="upload-demo"
action="00"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:on-change = "onchangeHandle"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList"
:auto-upload="false"
>
<el-button size="small" type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500kb
</div>
</template>
</el-upload>
<el-progress :percentage="obj.currentLoading" :format="format" />
</template>
<script>
// https://www.jianshu.com/p/08524828f84b
// https://zhuanlan.zhihu.com/p/68271019
// 步骤简述 1图片分割 2formdata 保存数据上传后台
import {defineComponent, reactive} from 'vue'
import { ElMessage,ElMessageBox } from 'element-plus'
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String
},
setup () {
const fileList = reactive([])
const obj = reactive({
currentLoading: 0,
current: 0
})
function handleRemove(file, fileList) {
console.log(file, fileList)
}
function handlePreview(file) {
console.log(file)
}
function handleExceed() {
ElMessage(
`www`
)
}
function beforeRemove() {
ElMessage(`Cancel the transfert of ?`)
}
const sliceImg = (file, piece = 1024 * 1024 * 1) => { // 分割图片
let totalSize = file.size; // 文件总大小
let start = 0; // 每次上传的开始字节
let end = start + piece; // 每次上传的结尾字节
let chunks = []
while (start < totalSize) {
// 根据长度截取每次需要上传的数据
// File对象继承自Blob对象,因此包含slice方法
let blob = file.raw.slice(start, end);
chunks.push(blob)
start = end;
end = start + piece;
}
return chunks
}
const onchangeHandle = (file, fileList) => {
console.log(file, fileList)
let imgData = sliceImg(file)
let loading = Math.floor(100/imgData.length) // 进度条每次的进度
let time = imgData.length // 总共要发几次请求
saveImg(imgData, loading, time, obj)
}
const saveImg = (arr, loading, time, obj) => {
const formData = new FormData()
const key = 'chunk' + obj.current
formData.append('chunk', arr[obj.current])
formData.append('filename', key)
// 请求接口去
setTimeout(() => {
obj.current++
obj.currentLoading = loading *obj.current
if (obj.current < time) {
saveImg(arr, loading, time, obj)
} else {
obj.currentLoading = 100
ElMessageBox.alert('上传成功', '提示', {
confirmButtonText: '确定',
callback: () => {
console.log('成')
},
})
}
}, 2000)
}
return {
handleRemove,
handlePreview,
handleExceed,
beforeRemove,
fileList,
onchangeHandle,
obj
}
}
})
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>