在 Vue 项目中,为避免在 iframe 加载完成后才绑定监听导致
postMessage 丢失的问题,推荐通过
v-if 控制 iframe 的加载时机。这样可以确保监听逻辑和 iframe 生命周期同步,保证消息可靠发送。
<template>
<div>
<!-- 弹窗组件 -->
<el-dialog v-model="visible" title="图片精修工具" width="80%" height="80%">
<!-- 只有在弹窗可见时才加载 iframe,确保 onload 与监听逻辑生效 -->
<iframe
v-if="visible"
id="xiangji-image-editor"
ref="editorIframe"
title="象寄图片精修工具"
style="width: 100%; height: 80vh;"
:src="editorUrl"
frameborder="0"
@load="onIframeLoad"
></iframe>
</el-dialog>
<!-- 示例按钮 -->
<el-button type="primary" @click="openEditor">打开精修工具</el-button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
const visible = ref(false);
const editorIframe = ref(null);
const editorUrl = 'https://www.xiangjifanyi.com/image-editor/#/?lang=CHS';
function openEditor() {
visible.value = true;
}
// iframe 加载完成后发送 postMessage
function onIframeLoad() {
const iframe = editorIframe.value;
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage(
{
name: 'XJ_IMAGE_EDITOR_REQUESTIDS',
requestIds: ['f350044c1c722a35'],
},
'https://www.xiangjifanyi.com'
);
}
}
// 监听来自 iframe 的消息
function handleMessage(e) {
const { name, all } = e.data || {};
if (e.origin === 'https://www.xiangjifanyi.com' && name === 'XJ_IMAGE_EDITOR_URL') {
console.log('精修结果:', all);
}
}
onMounted(() => {
window.addEventListener('message', handleMessage);
});
onBeforeUnmount(() => {
window.removeEventListener('message', handleMessage);
});
</script>
✅ 关键点说明:
• 使用 v-if="visible" 确保 iframe 仅在弹窗打开时才被创建。
• 通过 @load 监听 iframe 加载完成,立即发送 postMessage,防止事件丢失。
• 在组件挂载时注册 message 监听,在销毁时移除,防止重复绑定。