效果:
下面是一个 Vue 3 (setup script) + WangEditor 5 的示例,演示了如何配置编辑器以支持粘贴图片并“上传”(此处为模拟上传,实际中你需要对接后端接口)。
主要思路:
-
安装依赖:
- @wangeditor/editor: WangEditor 核心库。
- @wangeditor/editor-for-vue: WangEditor 的 Vue 3 组件封装。
-
配置 editorConfig:
-
通过 MENU_CONF['uploadImage'] 来配置图片上传。
-
关键是使用 customUpload 方法。当用户粘贴、拖拽或选择图片时,此方法会被调用。
-
customUpload(file, insertFn):
-
file: File 对象,即用户粘贴或选择的图片文件。
-
insertFn(url, alt, href): 一个回调函数,你需要调用它来将图片插入到编辑器中。
- url: 图片的最终可访问 URL。
- alt: 图片的 alt 文本(可选)。
- href: 图片链接(可选)。
-
-
-
模拟上传:
- 在 customUpload 中,我们会接收到 file 对象。
- 为了演示,我们将使用 URL.createObjectURL(file) 生成一个临时的本地 URL,并模拟一个异步上传过程(例如使用 setTimeout)。
- 在实际项目中,你需要将 file 通过 FormData 发送到你的后端服务器,服务器保存图片后返回一个永久的图片 URL,然后你再调用 insertFn。
步骤:
1. 安装依赖:
npm install @wangeditor/editor @wangeditor/editor-for-vue
# 或者
yarn add @wangeditor/editor @wangeditor/editor-for-vue
2. 创建组件 WangEditorDemo.vue:
<template>
<div style="border: 1px solid #ccc; margin-top: 20px;">
<!-- 工具栏 -->
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
mode="default"
/>
<!-- 编辑器 -->
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="valueHtml"
:defaultConfig="editorConfig"
mode="default"
@onCreated="handleCreated"
@onChange="handleChange"
/>
</div>
<div style="margin-top: 10px;">
<p>编辑器内容:</p>
<div v-html="valueHtml"></div>
</div>
</template>
<script setup>
import { ref, shallowRef, onBeforeUnmount, onMounted } from 'vue';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import '@wangeditor/editor/dist/css/style.css'; // 引入 Wangeditor 样式
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref('<p>Hello WangEditor!</p><p>尝试从剪贴板粘贴一张图片,或者拖拽图片进来。</p>');
// 工具栏配置
const toolbarConfig = {
// 在此处配置工具栏,不需要的可以不配置
// excludeKeys: ['group-image'], // 例如,如果完全依赖粘贴上传,可以隐藏默认的图片上传按钮
};
// 编辑器配置
const editorConfig = {
placeholder: '请输入内容...',
MENU_CONF: {
// 图片上传配置
uploadImage: {
// 自定义图片上传逻辑
// file 即选中的文件,async customUpload 返回的是一个数组 [{ url, alt, href }]
async customUpload(file, insertFn) {
console.log('Pasted/Uploaded file:', file);
// --- 模拟上传过程 ---
// 1. 创建 FormData 对象
// const formData = new FormData();
// formData.append('file', file); // 'file' 是你后端接口接收的字段名
// formData.append('otherParam', 'value'); // 其他参数
// 2. 发起 AJAX 请求 (例如使用 fetch 或 axios)
// try {
// const response = await fetch('/api/upload-image', { // 替换为你的后端上传接口
// method: 'POST',
// body: formData,
// // headers: { 'Authorization': 'Bearer your_token_if_needed' }
// });
// if (!response.ok) {
// throw new Error(`Upload failed: ${response.statusText}`);
// }
// const result = await response.json(); // 假设后端返回 { errno: 0, data: { url: '...', alt: '...', href: '...' } }
//
// if (result.errno === 0 && result.data && result.data.url) {
// // 上传成功,调用 insertFn 插入图片
// insertFn(result.data.url, result.data.alt || file.name, result.data.href || result.data.url);
// console.log('Image uploaded and inserted:', result.data.url);
// } else {
// alert(`上传失败: ${result.message || '未知错误'}`);
// console.error('Upload error from server:', result);
// }
// } catch (error) {
// alert(`上传出错: ${error.message}`);
// console.error('Upload fetch error:', error);
// }
// --- 模拟上传过程结束 ---
// --- DEMO: 使用本地 Blob URL 模拟上传成功 ---
// 提示:URL.createObjectURL 创建的 URL 只在当前文档生命周期内有效
// 实际项目中,你需要上传到服务器并获取一个永久的 URL
console.log('Simulating upload for demo purposes...');
await new Promise(resolve => setTimeout(resolve, 1500)); // 模拟网络延迟
const url = URL.createObjectURL(file);
const alt = file.name; // 使用文件名作为 alt
const href = url; // 可以让图片本身可点击,并链接到原图
// 调用 insertFn 插入图片
// insertFn(url, alt, href)
insertFn(url, alt, href);
console.log(`Simulated upload complete. Inserted image with local URL: ${url}`);
// 注意: 如果使用 createObjectURL,理论上在图片不再需要时(例如编辑器销毁或图片被删除时)
// 应该调用 URL.revokeObjectURL(url) 来释放资源。
// 但在 WangEditor 中,编辑器内部可能会处理,或者对于简单演示,浏览器关闭时也会释放。
// --- DEMO 结束 ---
},
// 其他配置项 (根据 WangEditor 文档按需配置)
// server: '/api/upload', // 如果你不想用 customUpload,可以直接配置服务器地址,但这样粘贴的自定义处理会复杂
fieldName: 'file', // 上传时传递的文件表单名,默认 'wangeditor-uploaded-image'
maxFileSize: 5 * 1024 * 1024, // 5M
allowedFileTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp'], // 允许的文件类型
// meta: { token: 'xxx', a: 100 }, // 上传时附带的额外参数
// headers: { Authorization: 'Bearer your_token' }, // 自定义请求头
// 粘贴图片时的行为,默认为 'upload',即触发上传逻辑
// 如果只想 base64 编码,可以设为 'base64',但不推荐大图片用 base64
pasteIgnoreImg: false, // 是否忽略粘贴的图片,默认为 false
// onInserted(files) { console.log('图片已插入编辑器', files); },
// onProgress(progress) { console.log('上传进度', progress); }, // 0-100
// onSuccess(file, res) { console.log(`${file.name} 上传成功`, res); },
// onFailed(file, res) { console.log(`${file.name} 上传失败`, res); },
// onError(file, err, res) { console.error(`${file.name} 上传出错`, err, res); },
},
// 其他 MENU_CONF 配置...
// 例如:配置粘贴文本的过滤
// pasteTextHandle: (html) => {
// console.log('Pasted HTML:', html);
// // 在这里可以对粘贴的 HTML 内容进行处理
// // return html.replace(/<p>/g, '<span>').replace(/<\/p>/g, '</span>');
// return html;
// }
},
};
// 编辑器创建时的回调
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
console.log('Editor created:', editor.getAllMenuKeys());
};
// 编辑器内容变化时的回调
const handleChange = (editor) => {
// console.log('Content changed:', editor.getHtml());
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
onMounted(() => {
// 可以在这里做一些初始化,但王编辑器的主要配置在 editorConfig 中
});
</script>
<style scoped>
/* 可以添加一些组件局部样式 */
</style>
3. 在你的 App.vue 或其他父组件中使用:
<template>
<div>
<h1>WangEditor 5 in Vue 3 Demo</h1>
<WangEditorDemo />
</div>
</template>
<script setup>
import WangEditorDemo from './components/WangEditorDemo.vue';
</script>
<style>
/* 全局样式,如果需要 */
body {
margin: 20px;
}
</style>
解释:
-
@wangeditor/editor-for-vue: 提供了 Editor 和 Toolbar 组件。
-
shallowRef for editorRef: WangEditor 官方推荐使用 shallowRef 来存储编辑器实例,因为编辑器实例本身比较复杂,不需要深度响应。
-
editorConfig.MENU_CONF.uploadImage: 这是配置图片上传的核心。
-
customUpload(file, insertFn) :
- 当用户粘贴图片(或其他方式如拖拽、点击上传按钮选择文件)时,WangEditor 会捕获到图片数据并将其包装成一个 File 对象,然后调用这个 customUpload 方法。
- file: 就是这个图片文件。
- insertFn: 你必须调用此函数,并传入图片的最终 URL (以及可选的 alt 和 href),WangEditor 才会将
标签插入到编辑区域。
-
模拟上传 vs 实际上传:
- 模拟 (Demo中) : 我们使用 URL.createObjectURL(file) 生成一个临时的、仅在当前浏览器会话中有效的对象 URL。这对于本地演示非常方便,但这个 URL 不能被其他人访问,也不能持久保存。
- 实际: 你需要将 file 对象通过 fetch 或 axios 发送到你的后端 API。后端接收文件、保存到服务器或云存储,并返回一个公开可访问的永久 URL。然后你用这个返回的 URL 去调用 insertFn。示例代码中注释掉了实际上传的逻辑框架。
-
pasteIgnoreImg: false: 确保粘贴的图片不会被忽略,而是触发上传流程。这是默认行为,但明确写出来有助于理解。
-
-
生命周期管理:
- handleCreated: 编辑器创建后,将实例赋值给 editorRef。
- onBeforeUnmount: 组件销毁前,必须调用 editor.destroy() 来销毁编辑器实例,释放资源,防止内存泄漏。
====================== 核心 ======================
MENU_CONF: {
// 图片上传配置
uploadImage: {
// 自定义图片上传逻辑
// file 即选中的文件,async customUpload 返回的是一个数组 [{ url, alt, href }]
async customUpload(file, insertFn) {
console.log('Pasted/Uploaded file:', file);
// --- 模拟上传过程 ---
// 1. 创建 FormData 对象
// const formData = new FormData();
// formData.append('file', file); // 'file' 是你后端接口接收的字段名
// formData.append('otherParam', 'value'); // 其他参数
// 2. 发起 AJAX 请求 (例如使用 fetch 或 axios)
// try {
// const response = await fetch('/api/upload-image', { // 替换为你的后端上传接口
// method: 'POST',
// body: formData,
// // headers: { 'Authorization': 'Bearer your_token_if_needed' }
// });
// if (!response.ok) {
// throw new Error(`Upload failed: ${response.statusText}`);
// }
// const result = await response.json(); // 假设后端返回 { errno: 0, data: { url: '...', alt: '...', href: '...' } }
//
// if (result.errno === 0 && result.data && result.data.url) {
// // 上传成功,调用 insertFn 插入图片
// insertFn(result.data.url, result.data.alt || file.name, result.data.href || result.data.url);
// console.log('Image uploaded and inserted:', result.data.url);
// } else {
// alert(`上传失败: ${result.message || '未知错误'}`);
// console.error('Upload error from server:', result);
// }
// } catch (error) {
// alert(`上传出错: ${error.message}`);
// console.error('Upload fetch error:', error);
// }
// --- 模拟上传过程结束 ---
// --- DEMO: 使用本地 Blob URL 模拟上传成功 ---
// 提示:URL.createObjectURL 创建的 URL 只在当前文档生命周期内有效
// 实际项目中,你需要上传到服务器并获取一个永久的 URL
console.log('Simulating upload for demo purposes...');
await new Promise(resolve => setTimeout(resolve, 1500)); // 模拟网络延迟
const url = URL.createObjectURL(file);
const alt = file.name; // 使用文件名作为 alt
const href = url; // 可以让图片本身可点击,并链接到原图
// 调用 insertFn 插入图片
// insertFn(url, alt, href)
insertFn(url, alt, href);
console.log(`Simulated upload complete. Inserted image with local URL: ${url}`);
// 注意: 如果使用 createObjectURL,理论上在图片不再需要时(例如编辑器销毁或图片被删除时)
// 应该调用 URL.revokeObjectURL(url) 来释放资源。
// 但在 WangEditor 中,编辑器内部可能会处理,或者对于简单演示,浏览器关闭时也会释放。
// --- DEMO 结束 ---
},
// 其他配置项 (根据 WangEditor 文档按需配置)
// server: '/api/upload', // 如果你不想用 customUpload,可以直接配置服务器地址,但这样粘贴的自定义处理会复杂
fieldName: 'file', // 上传时传递的文件表单名,默认 'wangeditor-uploaded-image'
maxFileSize: 5 * 1024 * 1024, // 5M
allowedFileTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp'], // 允许的文件类型
// meta: { token: 'xxx', a: 100 }, // 上传时附带的额外参数
// headers: { Authorization: 'Bearer your_token' }, // 自定义请求头
// 粘贴图片时的行为,默认为 'upload',即触发上传逻辑
// 如果只想 base64 编码,可以设为 'base64',但不推荐大图片用 base64
pasteIgnoreImg: false, // 是否忽略粘贴的图片,默认为 false
// onInserted(files) { console.log('图片已插入编辑器', files); },
// onProgress(progress) { console.log('上传进度', progress); }, // 0-100
// onSuccess(file, res) { console.log(`${file.name} 上传成功`, res); },
// onFailed(file, res) { console.log(`${file.name} 上传失败`, res); },
// onError(file, err, res) { console.error(`${file.name} 上传出错`, err, res); },
},
// 其他 MENU_CONF 配置...
// 例如:配置粘贴文本的过滤
// pasteTextHandle: (html) => {
// console.log('Pasted HTML:', html);
// // 在这里可以对粘贴的 HTML 内容进行处理
// // return html.replace(/<p>/g, '<span>').replace(/<\/p>/g, '</span>');
// return html;
// }
},
=========有用!!!!!!!!!!!!===================!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<template>
<div style="border: 1px solid #ccc; margin-top: 20px;">
<!-- 工具栏 -->
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
mode="default"
/>
<!-- 编辑器 -->
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="valueHtml"
:defaultConfig="editorConfig"
mode="default"
@onCreated="handleCreated"
@onChange="handleChange"
/>
</div>
<!-- <div style="margin-top: 10px;">
<p>编辑器内容:</p>
<div v-html="valueHtml"></div>
</div> -->
</template>
<script setup>
import { ref, shallowRef, onBeforeUnmount, onMounted, watch } from 'vue';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import '@wangeditor/editor/dist/css/style.css'; // 引入 Wangeditor 样式
// 定义 props 和 emits
const props = defineProps({
modelValue: {
type: String,
default: ''
}
});
const emit = defineEmits(['update:modelValue']);
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref(props.modelValue || '<p></p>');
// 监听 modelValue 变化
watch(() => props.modelValue, (newVal) => {
if (newVal !== valueHtml.value) {
valueHtml.value = newVal;
}
});
// 监听 valueHtml 变化,触发 emit
watch(valueHtml, (newVal) => {
emit('update:modelValue', newVal);
});
// 工具栏配置
const toolbarConfig = {
// 在此处配置工具栏,不需要的可以不配置
// excludeKeys: ['group-image'], // 例如,如果完全依赖粘贴上传,可以隐藏默认的图片上传按钮
};
// 编辑器配置
const editorConfig = {
placeholder: 'Please input content...',
MENU_CONF: {
// 图片上传配置
uploadImage: {
// 自定义图片上传逻辑
async customUpload(file, insertFn) {
console.log('图片上传触发', file);
try {
console.log('开始处理图片上传...');
const url = URL.createObjectURL(file);
const alt = file.name || 'pasted image';
const href = url;
// 调用 insertFn 插入图片
insertFn(url, alt, href);
console.log(`图片上传完成,URL: ${url}`);
} catch (error) {
console.error('图片上传失败:', error);
alert('Image upload failed, please try again');
}
},
fieldName: 'file',
maxFileSize: 10 * 1024 * 1024, // 10M
allowedFileTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp'],
// 关键配置:确保粘贴图片能正常工作
pasteIgnoreImg: false,
// 添加事件回调来调试
onInserted(files) {
console.log('图片已插入编辑器', files);
},
onSuccess(file, res) {
console.log(`${file.name} 上传成功`, res);
},
onFailed(file, res) {
console.log(`${file.name} 上传失败`, res);
},
onError(file, err, res) {
console.error(`${file.name} 上传出错`, err, res);
},
}
},
// 确保编辑器能接收粘贴事件
readOnly: false,
autoFocus: false
};
// 编辑器创建时的回调
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
console.log('Editor created:', editor.getAllMenuKeys());
// 添加粘贴图片监听器
const editorDom = editor.getEditableContainer();
if (editorDom) {
editorDom.addEventListener('paste', handlePasteImage);
console.log('已添加粘贴监听器');
}
};
// 处理粘贴图片
const handlePasteImage = (event) => {
console.log('粘贴事件触发', event);
const clipboardData = event.clipboardData;
if (!clipboardData) return;
const items = clipboardData.items;
if (!items || items.length === 0) return;
// 查找图片类型
for (let i = 0; i < items.length; i++) {
const item = items[i];
console.log('粘贴项目类型:', item.type);
if (item.type.includes('image')) {
console.log('检测到图片粘贴');
event.preventDefault(); // 阻止默认粘贴行为
const file = item.getAsFile();
if (file) {
console.log('获取到图片文件:', file);
// 创建临时URL
const url = URL.createObjectURL(file);
const alt = 'pasted image';
// 插入图片到编辑器
const editor = editorRef.value;
if (editor) {
console.log('插入图片到编辑器:', url);
editor.dangerouslyInsertHtml(`<img src="${url}" alt="${alt}" style="max-width: 100%; height: auto;" />`);
}
}
break;
}
}
};
// 编辑器内容变化时的回调
const handleChange = (editor) => {
// console.log('Content changed:', editor.getHtml());
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
// 移除粘贴监听器
const editorDom = editor.getEditableContainer();
if (editorDom) {
editorDom.removeEventListener('paste', handlePasteImage);
}
editor.destroy();
});
// 移除全局的paste监听器,让编辑器自己处理粘贴事件
onMounted(() => {
console.log('WangEditor 组件已挂载,粘贴功能已就绪');
});
</script>
<style scoped>
/* 可以添加一些组件局部样式 */
</style>
====上述是本地上传,没有走接口,下面这个示例是联调接口的示例,并用接口展示图片 =====
<template>
<div style="border: 1px solid #ccc; margin-top: 20px">
<!-- 工具栏 -->
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
mode="default"
/>
<!-- 编辑器 -->
<Editor
style="height: 200px; overflow-y: hidden"
v-model="valueHtml"
:defaultConfig="editorConfig"
mode="default"
@onCreated="handleCreated"
@onChange="handleChange"
/>
</div>
<!-- <div style="margin-top: 10px;">
<p>编辑器内容:</p>
<div v-html="valueHtml"></div>
</div> -->
</template>
<script setup>
import { ref, shallowRef, onBeforeUnmount, onMounted, watch } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import "@wangeditor/editor/dist/css/style.css"; // 引入 Wangeditor 样式
import { uploadFileApiNew } from "@/api/featuredPapers/index";
import { ElMessage, ElMessageBox } from "element-plus";
// 定义 props 和 emits
const props = defineProps({
modelValue: {
type: String,
default: "",
},
});
const emit = defineEmits(["update:modelValue"]);
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref(props.modelValue || "<p></p>");
// 监听 modelValue 变化
watch(
() => props.modelValue,
(newVal) => {
if (newVal !== valueHtml.value) {
valueHtml.value = newVal;
}
}
);
// 监听 valueHtml 变化,触发 emit
watch(valueHtml, (newVal) => {
emit("update:modelValue", newVal);
});
// 工具栏配置
const toolbarConfig = {
// 只保留文本和图片相关的工具栏按钮
toolbarKeys: [
'bold',
'italic',
'underline',
'fontSize',
'fontFamily',
'color',
'bgColor',
'|',
'uploadImage',
'|',
'justifyLeft',
'justifyCenter',
'justifyRight',
]
};
// 编辑器配置
const editorConfig = {
placeholder: "Please input content...",
MENU_CONF: {
// 图片上传配置
uploadImage: {
// 自定义图片上传逻辑
async customUpload(file, insertFn) {
console.log("图片上传触发", file);
try {
// console.log('开始处理图片上传...');
// const url = URL.createObjectURL(file);
// const alt = file.name || 'pasted image';
// const href = url;
const uploadResponse = await uploadFileApiNew(file);
if (uploadResponse.code === 2000 && uploadResponse.data) {
const fileId = uploadResponse.data.uploadFileData.id || "";
// https://chatgpt.com/share/68592c2a-44e0-8000-a162-4a847e6a745a
// const imgUrl = URL.createObjectURL(file); // 只能上传的那个人的电脑才能看 blob
const imageData = {
url: imgUrl,
name: file.name,
fileId: fileId,
};
ElMessage.success("图片上传成功");
} else {
ElMessage.error("图片上传失败");
}
// 调用 insertFn 插入图片
insertFn(url, alt, href);
console.log(`图片上传完成,URL: ${url}`);
} catch (error) {
console.error("图片上传失败:", error);
alert("Image upload failed, please try again");
}
},
fieldName: "file",
maxFileSize: 10 * 1024 * 1024, // 10M
allowedFileTypes: [
"image/jpeg",
"image/png",
"image/gif",
"image/bmp",
"image/webp",
],
// 关键配置:确保粘贴图片能正常工作
pasteIgnoreImg: false,
// 添加事件回调来调试
onInserted(files) {
console.log("图片已插入编辑器", files);
},
onSuccess(file, res) {
console.log(`${file.name} 上传成功`, res);
},
onFailed(file, res) {
console.log(`${file.name} 上传失败`, res);
},
onError(file, err, res) {
console.error(`${file.name} 上传出错`, err, res);
},
},
},
// 确保编辑器能接收粘贴事件
readOnly: false,
autoFocus: false,
};
// 编辑器创建时的回调
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
console.log("Editor created:", editor.getAllMenuKeys());
// 添加粘贴图片监听器
const editorDom = editor.getEditableContainer();
if (editorDom) {
editorDom.addEventListener("paste", handlePasteImage);
console.log("已添加粘贴监听器");
}
};
// 处理粘贴图片
const handlePasteImage = async (event) => {
console.log("粘贴事件触发", event);
const clipboardData = event.clipboardData;
if (!clipboardData) return;
const items = clipboardData.items;
if (!items || items.length === 0) return;
// 查找图片类型
for (let i = 0; i < items.length; i++) {
const item = items[i];
console.log("粘贴项目类型:", item.type);
if (item.type.includes("image")) {
console.log("检测到图片粘贴");
event.preventDefault(); // 阻止默认粘贴行为
const file = item.getAsFile();
if (file) {
console.log("获取到图片文件:", file);
// 创建临时URL
// const url = URL.createObjectURL(file);
const alt = "pasted image";
const uploadResponse = await uploadFileApiNew(file);
if (uploadResponse.code === 2000 && uploadResponse.data) {
const fileId = uploadResponse.data.uploadFileData.id || "";
// const imgUrl = URL.createObjectURL(file);
const realUrl = `/api/poster/show/image/${fileId}`; // ✅ 使用后端真实 URL
ElMessage.success("粘贴---图片上传成功");
// 插入图片到编辑器
const editor = editorRef.value;
if (editor) {
editor.dangerouslyInsertHtml(
`<img src="${realUrl}" alt="${alt}" style="max-width: 100%; height: auto;" />`
);
}
} else {
ElMessage.error("粘贴---图片上传失败");
}
}
break;
}
}
};
// 编辑器内容变化时的回调
const handleChange = (editor) => {
// console.log('Content changed:', editor.getHtml());
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
// 移除粘贴监听器
const editorDom = editor.getEditableContainer();
if (editorDom) {
editorDom.removeEventListener("paste", handlePasteImage);
}
editor.destroy();
});
// 移除全局的paste监听器,让编辑器自己处理粘贴事件
onMounted(() => {
console.log("WangEditor 组件已挂载,粘贴功能已就绪");
});
</script>