wangeditor超过1m的图片上传前压缩照片,要怎么实现?一直搞不来
<template>
<div class="container">
<Toolbar
style="border: 1px solid #ccc; width: 1180px;"
:editor="editorRef"
:default-config="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; width: 1180px; overflow-y: hidden; border: 1px solid #ccc;"
v-model="valueHtml"
:default-config="editorConfig"
:mode="mode"
@on-created="handleCreated"
/>
</div>
</template>
<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css';
import {onBeforeUnmount, ref, shallowRef, watch} from 'vue';
import type {IEditorConfig, IToolbarConfig} from '@wangeditor/editor'; // 使用 type 导入
import {Editor, Toolbar} from '@wangeditor/editor-for-vue';
import {ElMessage} from "element-plus";
const props = defineProps<{
modelValue: string;
mode?: string;
}>();
const emits = defineEmits<{
(e: 'update:modelValue', value: string): void;
}>();
const editorRef = shallowRef();
const valueHtml = ref<string>(props.modelValue || '');
watch(valueHtml, (newHtml) => {
emits('update:modelValue', newHtml);
});
const toolbarConfig: Partial<IToolbarConfig> = {
insertKeys: {
index: 0,
keys: ['uploadAttachment'],
},
};
const editorConfig: Partial<IEditorConfig> = {
hoverbarKeys: {
attachment: {
menuKeys: ['downloadAttachment'],
},
},
placeholder: '请输入内容...',
MENU_CONF: {
uploadImage: {
server: `${import.meta.env.VITE_API_BASE_URL}/Articles/uploadFile`,
fieldName: 'file',
maxFileSize: 20000 * 1024,
base64LimitSize: 5 * 1024 ,
withCredentials: true,
maxNumberOfFiles: 10,
methods: 'post',
metaWithUrl: true,
onBeforeUpload(file:File) {
console.log('文件对象:', JSON.stringify(file, null, 2)); // 输出文件对象的完整结构
// 获取第一个键
const key = Object.keys(file)[0];
// 通过键访问文件数据
const fileData = file[key];
console.log('文件数据:', fileData);
const fileName = fileData.name;
const fileSizeMB = (fileData.size / 1024 / 1024).toFixed(2);
console.log('文件名:', fileName);
console.log('文件大小:', fileSizeMB + 'MB');
console.log('文件类型:', fileData.type);
if (fileData.size / 1024 / 1024 > 1) {
console.log('文件超过1MB,开始压缩...');
console.log('fileData.data 属性:', Object.keys(fileData.data));
console.log('fileData.data.size:', fileData.data.size);
console.log('fileData.data.type:', fileData.data.type);
console.log('fileData.data.slice:', fileData.data.slice);
return new Promise((resolve, reject) => {
// 确保 fileData.data 是一个有效的 Blob 或 File 对象
if (!(fileData.data instanceof Blob)) {
reject(new Error('fileData.data 不是一个有效的 Blob 对象'));
return;
}
const reader = new FileReader();
reader.onload = function (event) {
const img = new Image();
img.onload = function () {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 设置压缩后的宽度和高度
const MAX_WIDTH = 800;
const MAX_HEIGHT = 800;
let width = img.width;
let height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
// 绘制图像到 canvas
ctx.drawImage(img, 0, 0, width, height);
// 将 canvas 转换为 Blob
canvas.toBlob((blob) => {
if (!blob) {
reject(new Error('压缩失败'));
return;
}
// 创建一个新的 File 对象
const compressedFile = new File([blob], fileName, {
type: fileData.type,
lastModified: Date.now(),
});
// 返回与原始 fileData 格式相同的对象
const compressedFileData = {
...fileData,
size: blob.size,
data: blob,
};
console.log('压缩后的文件大小:', (blob.size / 1024 / 1024).toFixed(2) + 'MB');
resolve(compressedFileData);
}, fileData.type, 0.7); // 0.7 是压缩质量,可以根据需要调整
};
img.src = event.target.result;
};
reader.onerror = reject;
reader.readAsDataURL(fileData); // 直接使用 fileData 作为 File 对象
});
} else {
console.log('文件大小小于或等于1MB,直接上传...');
return file;
}
},
onProgress(progress: number) {
console.log('上传进度:', progress);
},
onSuccess(file: File, res: any) {
console.log('上传成功:', file, res);
ElMessage.success('图片上传成功');
},
onFail(file: File, res: any) {
console.log('上传失败:', file, res);
ElMessage.error('图片上传失败');
},
onFinished(files: File[], res: any) {
console.log('所有文件上传完成:', files, res);
},
onFinishedFail(files: File[], res: any) {
console.log('文件上传失败:', files, res);
},
customInsert(res: any, insertFn: Function) {
// console.log('自定义插入:', res);
insertFn(res.data);
},
// 自定义插入图片
},
uploadVideo: {
server: `${import.meta.env.VITE_API_BASE_URL}/Articles/uploadFile`,
fieldName: 'file',
maxFileSize: 1000000 * 1024,
withCredentials: true,
maxNumberOfFiles: 10,
methods: 'post',
metaWithUrl: true,
onProgress(progress: number) {},
onSuccess(file: File, res: any) {},
onFail(file: File, res: any) {},
onFinished(files: File[], res: any) {},
onFinishedFail(files: File[], res: any) {},
customInsert(res: any, insertFn: Function) {
insertFn(res.data);
},
},
uploadAttachment: {
server: `${import.meta.env.VITE_API_BASE_URL}/Articles/uploadFile`,
fieldName: 'file',
maxFileSize: 1000000 * 1024,
withCredentials: true,
maxNumberOfFiles: 10,
methods: 'post',
metaWithUrl: true,
onProgress(progress: number) {},
onSuccess(file: File, res: any) {},
onFail(file: File, res: any) {},
onFinished(files: File[], res: any) {},
onFinishedFail(files: File[], res: any) {},
customInsert(res: any, file: File, insertFn: Function) {
insertFn(file.name, res.data);
},
},
},
};
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor) editor.destroy();
});
const handleCreated = (editorInstance: any) => {
editorRef.value = editorInstance;
};
</script>
<style scoped>
.container {
z-index: 2;
background: #fff;
float: left;
width: 1200px;
height: 100%;
}
</style>