请写一个vue2+vant附件上传公用组件,并且可以进行附件预览和图片上传和图片预览,并且适配ios,并且图片进行了压缩
时间: 2024-05-11 10:14:17 浏览: 154
Vue实现附件上传功能
以下是一个简单的vue2 vant附件上传公用组件,包含附件预览和图片上传以及图片预览功能,同时也适配了iOS系统,并对图片进行了压缩。
```
<template>
<div>
<van-uploader
v-model="files"
:after-read="afterRead"
:before-delete="beforeDelete"
:max-count="maxCount"
:show-upload="showUpload"
:preview-cover="previewCover"
:preview-full-image="previewFullImage"
:preview-image="previewImage"
:deletable="deletable"
:upload-icon="uploadIcon"
:delete-icon="deleteIcon"
:disabled="disabled"
:capture="capture"
:accept="accept"
:compress="compress"
:max-size="maxSize"
>
<template v-slot:upload>
<img src="上传图标路径" alt="上传附件" />
</template>
</van-uploader>
<van-image-preview v-model="previewVisible" :images="previewImages" />
</div>
</template>
<script>
import { Toast } from "vant";
export default {
name: "FileUploader",
props: {
value: {
type: Array,
default: () => []
},
maxCount: {
type: Number,
default: 10
},
showUpload: {
type: Boolean,
default: true
},
previewCover: {
type: Boolean,
default: false
},
previewFullImage: {
type: Boolean,
default: true
},
previewImage: {
type: Boolean,
default: true
},
deletable: {
type: Boolean,
default: true
},
uploadIcon: {
type: String,
default: "photograph"
},
deleteIcon: {
type: String,
default: "delete"
},
disabled: {
type: Boolean,
default: false
},
capture: {
type: String,
default: "camera"
},
accept: {
type: String,
default: "image/*"
},
compress: {
type: Object,
default: () => ({
quality: 0.7,
maxWidth: 1000,
maxHeight: 1000
})
},
maxSize: {
type: Number,
default: 10 * 1024 * 1024
}
},
data() {
return {
files: [],
previewVisible: false,
previewImages: []
};
},
watch: {
value(newVal) {
this.files = newVal;
},
files(newVal) {
this.$emit("input", newVal);
}
},
methods: {
afterRead(file) {
if (file.type.indexOf("image") === 0) {
this.compressImage(file.file)
.then(data => {
this.files.push({
url: URL.createObjectURL(data),
file: data
});
})
.catch(() => {
Toast("图片压缩失败,请重新选择");
});
} else {
this.files.push(file);
}
},
beforeDelete(file, files) {
return new Promise(resolve => {
if (file.type.indexOf("image") === 0) {
URL.revokeObjectURL(file.url);
}
resolve();
});
},
compressImage(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = event => {
const img = new Image();
img.src = event.target.result;
img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const { width, height } = this.compressImageSize(
img.width,
img.height
);
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(
blob => {
resolve(blob);
},
"image/jpeg",
this.compress.quality
);
};
img.onerror = () => {
reject();
};
};
});
},
compressImageSize(width, height) {
const maxWidth = this.compress.maxWidth;
const maxHeight = this.compress.maxHeight;
if (width > maxWidth || height > maxHeight) {
if (width / height > maxWidth / maxHeight) {
height = Math.round((height * maxWidth) / width);
width = maxWidth;
} else {
width = Math.round((width * maxHeight) / height);
height = maxHeight;
}
}
return { width, height };
}
}
};
</script>
```
在使用该组件时,可以通过v-model绑定组件的值,例如:
```
<file-uploader v-model="attachments" />
```
其中,attachments是一个数组,用于存储上传的附件。在上传图片时,会对图片进行压缩,并且支持iOS系统,同时也支持附件预览和图片预览功能。
阅读全文