203 lines
6.1 KiB
Vue
203 lines
6.1 KiB
Vue
<template>
|
|
<!-- :after-read="afterRead" -->
|
|
<!-- :after-read="afterRead" -->
|
|
<van-uploader
|
|
v-model="fileList"
|
|
:disabled="disableImg"
|
|
multiple
|
|
:deletable="deletable"
|
|
:max-count="1"
|
|
:afterRead="afterRead"
|
|
:before-delete="delImg"
|
|
@click-upload="onUpload"
|
|
accept="image/*"
|
|
>
|
|
<div class="uploader" >
|
|
<van-icon name="plus" class="uploader-icon" />
|
|
</div>
|
|
</van-uploader>
|
|
</template>
|
|
|
|
<script>
|
|
import { uploadFile } from '@/api/api.js'
|
|
import { chooseAlbumAndTakePhoto } from '@/utils/dsbridge'
|
|
import { getImageBlobUrl } from '@/utils/index'
|
|
export default {
|
|
props: {
|
|
type: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
value: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
deletable: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
disableImg: false,
|
|
fileList: [],
|
|
}
|
|
},
|
|
watch: {
|
|
// 父组件异步回填(如历史记录 getHistory 晚于 mounted)时同步列表;
|
|
// 上传后父组件把 value 改写为 [url字符串] 时不覆盖本地回显
|
|
value: {
|
|
handler(val) {
|
|
if (val && val.length && val.every(item => typeof item === 'object')) {
|
|
this.fileList = val.map(item => ({ ...item, isImage: true }))
|
|
}
|
|
},
|
|
immediate: true,
|
|
deep: true,
|
|
},
|
|
},
|
|
beforeDestroy() {
|
|
this.fileList = []
|
|
},
|
|
methods: {
|
|
base64ToFile(data, fileName) {
|
|
const dataArr = data.split(',')
|
|
const byteString = window.atob(dataArr[1])
|
|
const options = {
|
|
type: 'image/jpeg',
|
|
endings: 'native',
|
|
}
|
|
const u8Arr = new Uint8Array(byteString.length)
|
|
for (let i = 0; i < byteString.length; i++) {
|
|
u8Arr[i] = byteString.charCodeAt(i)
|
|
}
|
|
let formData = new FormData()
|
|
let fileOfBlob = new File([u8Arr], fileName + '.jpg', options) //返回文件流
|
|
formData.append('file', fileOfBlob)
|
|
return formData
|
|
},
|
|
// 上传图片调用原生的方法 获取到绝对路径调用getImageFileFromUrl
|
|
onUpload() {
|
|
console.log('--------chooseAlbumAndTakePhoto---', 'onUpload')
|
|
chooseAlbumAndTakePhoto(async (data) => {
|
|
console.log('--------onUpload---', data)
|
|
let d = 'data:image/jpeg;base64,' + data
|
|
this.fileIamge = d
|
|
let params = this.base64ToFile(d, new Date().getTime().toString())
|
|
console.log('--------params---', params)
|
|
const res = await uploadFile(params)
|
|
console.log('--------res---', res)
|
|
if (res.code == 0) {
|
|
const blobUrl = await getImageBlobUrl(res.data.attach_id)
|
|
console.log('--------回显 blobUrl---', blobUrl)
|
|
if (!blobUrl) return
|
|
this.fileList.push({
|
|
fileName: res.data.original_name,
|
|
fileId: res.data.attach_id,
|
|
url: blobUrl,
|
|
isImage: true,
|
|
})
|
|
this.$emit('onUpload', this.fileList, this.type)
|
|
}
|
|
})
|
|
},
|
|
async afterRead(file) {
|
|
console.log('--------afterRead---', file)
|
|
this.disableImg = true
|
|
let params = new FormData()
|
|
params.append('file', file.file)
|
|
console.log(file.file)
|
|
console.log(params)
|
|
// console.log(decryptParseToJSON(a),77777777);
|
|
const res = await uploadFile(params)
|
|
if (res.code == 0) {
|
|
this.disableImg = false
|
|
this.$emit('afterRead', res.data, this.type)
|
|
}else{
|
|
this.disableImg = false
|
|
}
|
|
return true
|
|
},
|
|
beforeRead(file) {
|
|
if (file.size > 30000) {
|
|
return this.compressFiles(file)
|
|
} else {
|
|
return file
|
|
}
|
|
}, //压缩图片
|
|
compressFiles(fileObj) {
|
|
let type = fileObj.type
|
|
return new Promise((resolve, reject) => {
|
|
let reader = new FileReader()
|
|
reader.readAsDataURL(fileObj)
|
|
reader.onload = function (e) {
|
|
let image = new Image() //新建一个img标签(不嵌入DOM节点,仅做canvas操作)
|
|
image.src = e.target.result //让该标签加载base64格式的原图
|
|
image.onload = function () {
|
|
//图片加载完毕后再通过canvas压缩图片,否则图片还没加载完就压缩,结果图片是全黑的
|
|
let canvas = document.createElement('canvas'), //创建一个canvas元素
|
|
context = canvas.getContext('2d'), //context相当于画笔,里面有各种可以进行绘图的API
|
|
imageWidth = image.width / 2, //压缩后图片的宽度,这里设置为缩小一半
|
|
imageHeight = image.height / 2, //压缩后图片的高度,这里设置为缩小一半
|
|
data = '' //存储压缩后的图片
|
|
canvas.width = imageWidth //设置绘图的宽度
|
|
canvas.height = imageHeight //设置绘图的高度
|
|
|
|
//使用drawImage重新设置img标签中的图片大小,实现压缩。drawImage方法的参数可以自行查阅W3C
|
|
context.drawImage(image, 0, 0, imageWidth, imageHeight)
|
|
//使用toDataURL将canvas上的图片转换为base64格式
|
|
data = canvas.toDataURL(type)
|
|
canvas.toBlob(function (blob) {
|
|
const f = new File([blob], fileObj.name, { type })
|
|
resolve(f)
|
|
}, type)
|
|
}
|
|
}
|
|
})
|
|
},
|
|
delImg(file, detail) {
|
|
this.fileList.splice(detail.index, 1)
|
|
this.$emit('delImg', file, detail, this.type)
|
|
},
|
|
|
|
checkImgisUpload(list) {
|
|
if (this.fileList && list && this.fileList.length == list.length) {
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
<style lang='less' scoped>
|
|
/deep/ .van-uploader__preview-image {
|
|
padding: 10px;
|
|
box-sizing: border-box;
|
|
background: #fff;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
border-radius: 10px;
|
|
margin-left: 20px;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
/deep/ .van-uploader__preview-delete {
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.uploader {
|
|
width: 2.133333rem;
|
|
height: 2.133333rem;
|
|
background: #f7f7f7;
|
|
border-radius: 5px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin: 10px 0 10px 20px;
|
|
.uploader-icon {
|
|
font-size: 30px;
|
|
color: #ababab;
|
|
}
|
|
}
|
|
</style> |