<template> <!-- 公共图片上传 --> <div class="uploaderPage"> <!-- 上传图片 --> <van-uploader v-model="fileList" :before-read="beforeRead" @delete="deletePic" :max-count="maxCount" :max-size="50 * 1024 * 1024" @oversize="onOversize" :accept="acceptFormat" :disabled="isDisabled" > </van-uploader> <div v-if="acceptFormat == 'video/*'"> <!-- 显示视频列表 --> <div v-if="uploadList.length > 0"> <p v-for="item in uploadList" :key="item.name" class="van-ellipsis blueFont" @click="checkVideo(item.url)"> {{ item.originalName }} </p> </div> <!-- 查看视频弹窗 --> <!-- <van-popup v-model:show="showVideo" position="center" closeable class="uploadVideo" :style="{ width: '100%' }"> <vue3VideoPlay width="100%" title="视频" :src="videoUrl" :autoPlay="true" /> </van-popup> --> </div> </div> </template> <script setup name="uploaderPage"> import { onMounted, ref, onBeforeUnmount } from 'vue'; import { fileUpload, fileDelete } from '@/api/publicApi.js'; import { useStore } from '@/pinia/store.js'; import { getCurrentInstance } from 'vue'; // import 'vue3-video-play/dist/style.css'; // import vue3VideoPlay from 'vue3-video-play'; const props = defineProps({ //最大上传数 maxCount: { type: Number, default: 1, }, //保存的文件数组 saveFileArr: { type: Array, default: () => [], }, // 文件格式 acceptFormat: { type: String, default: 'image/*', // video/* }, // 是否禁用文件上传 isDisabled: { type: Boolean, default: false, }, }); const pinias = useStore(); const { proxy } = getCurrentInstance(); const emit = defineEmits(); const fileList = ref([]); //文件列表 const uploadList = ref([]); const maxCount = props.maxCount; //最大上传数 const showVideo = ref(false); const videoUrl = ref(''); // 查看视频弹窗 function checkVideo(url) { videoUrl.value = url; console.log(videoUrl.value, ' videoUrl.value'); showVideo.value = true; } // 开始上传图片 const beforeRead = async (file) => { // console.log(file, '原本上传的文件--'); // 压缩图片,大于500kb就压缩 let imgFile = null; if (file.size / 1024 > 500 && file.type.includes('image')) { imgFile = await blobToBase64(file, file.name); } else { imgFile = file; } // console.log(imgFile, '压缩后的图片文件获取'); pinias.showLoading(); let formData = new FormData(); let config = { headers: { 'Content-Type': 'multipart/form-data' }, }; formData.append('file', imgFile); let res = await fileUpload(formData, config); if (res && res.code == 200) { uploadList.value.push(res.data); console.log(uploadList.value, ' uploadList.value'); emit('update:saveFileArr', uploadList.value); //绑定的传值赋值 proxy.showSuccessToast('上传成功'); } else { fileList.value = []; let param = { id: imgFile.id, name: imgFile.name, status: 'error', }; fileList.value.push(param); proxy.showFailToast('上传失败'); } pinias.hideLoading(); }; // 图片删除 const deletePic = (file) => { console.log('图片删除--', file); let fileIndex = null; uploadList.value.map((item, index) => { if (file.file.name == (item.originalName || item.name)) { fileIndex = index; } }); // id为空时做逻辑删除,不调用删除接口 let id = uploadList.value[fileIndex].id; if (!!!id) { uploadList.value.splice(fileIndex, 1); } else { let ids = []; ids.push(id); fileDelete(ids).then((res) => { uploadList.value.splice(fileIndex, 1); proxy.showSuccessToast('删除成功'); }); } emit('update:saveFileArr', uploadList.value); //绑定的传值赋值 }; const blobToBase64 = async (blob, fileName) => { const reader = await new FileReader(); // 实例化一个reader文件 await reader.readAsDataURL(blob); // 添加二进制文件 return new Promise((resolve, reject) => { reader.onload = async (event) => { const base64 = await event.target.result; // 获取到它的base64文件 const scale = 0.6; // 设置缩放比例 (0-1) let file = await compressImg(base64, scale, fileName); resolve(file); }; }); }; // 压缩大小 const compressImg = (base64, scale, fileName) => { // 处理缩放,转换格式 // 用canvas来压缩 const img = new Image(); img.src = base64; return new Promise((resolve, reject) => { img.onload = async () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.setAttribute('width', img.width * scale); canvas.setAttribute('height', img.height * scale); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 转成base64 文件 base64 = canvas.toDataURL('image/jpeg', 0.8); //0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值 const arr = base64.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bytes = atob(arr[1]); const bytesLength = bytes.length; const u8arr = new Uint8Array(bytesLength); for (let i = 0; i < bytes.length; i++) { u8arr[i] = bytes.charCodeAt(i); } const file = await new File([u8arr], fileName, { type: mime }); resolve(file); }; }); }; function onOversize() { proxy.showFailToast('上传的文件最大为50M'); } onMounted(() => { console.log('修改时图片回显--', props.saveFileArr); // 修改时图片回显 fileList.value = []; uploadList.value = []; props.saveFileArr.map((item) => { let params = { id: item.id, name: item.name, originalName: item.originalName, file: { name: item.originalName }, status: 'success', url: item.url, }; fileList.value.push(params); uploadList.value.push(params); console.log(uploadList.value, ' uploadList.value1111'); }); }); onBeforeUnmount(() => { fileList.value = []; }); </script> <style lang="less"> .uploaderPage { width: 100%; .blueFont { color: #0c60e1; } } </style>