html-page
Some checks failed
/ surge (push) Successful in 2m45s
/ build-and-deploy-to-vercel (push) Successful in 3m24s
/ lint-build-and-check (push) Successful in 4m44s
/ playwright (push) Has been cancelled

This commit is contained in:
严浩
2025-04-09 18:01:33 +08:00
parent 0dcc47519f
commit 4e56d311f1
15 changed files with 8095 additions and 81 deletions

View File

@ -0,0 +1,100 @@
<script setup lang="ts">
const props = defineProps<{
// 定义传入的数据类型
data: Array<[number, number]>;
}>();
// 获取 iframe 的 DOM 引用
const iframeRef = ref<HTMLIFrameElement | null>(null);
// iframe 的 src URL
const src = computed(() => import.meta.env.BASE_URL + 'html-page/ConstellationDiagram.html');
// 标记 iframe 是否已加载完成并已发送初始化指令
const isIframeInitialized = ref(false);
// iframe 加载完成后的回调
function onIframeLoad() {
console.log('Vue 组件iframe 已加载');
// 发送初始化指令给 iframe
if (iframeRef.value?.contentWindow) {
console.log('Vue 组件:向 iframe 发送 INIT_WIDGET 指令');
// targetOrigin 设置为 '*' 为了简单,生产环境应指定确切来源
iframeRef.value.contentWindow.postMessage({ type: 'INIT_WIDGET' }, '*');
isIframeInitialized.value = true; // 标记已发送初始化指令
// 发送初始数据(如果已有)
// 稍微延迟发送,给 iframe 一点时间处理 INIT_WIDGET
// 注意:这是一种简化处理,更健壮的方式是等待 iframe 回复 WIDGET_READY 消息
setTimeout(() => {
if (props.data && props.data.length > 0 && isIframeInitialized.value) {
console.log('Vue 组件:发送初始数据');
sendDataToIframe(props.data);
}
}, 0); // 延迟 100 毫秒,可以根据实际情况调整
} else {
console.error('Vue 组件:无法访问 iframe 的 contentWindow');
}
}
// 将数据发送到 iframe 的函数
function sendDataToIframe(payload: Array<[number, number]>) {
// 确保 iframe 存在、其 contentWindow 可访问且已发送初始化指令
if (iframeRef.value?.contentWindow && isIframeInitialized.value) {
console.log('Vue 组件:向 iframe 发送数据:', payload);
iframeRef.value.contentWindow.postMessage({ type: 'FEED_DATA', payload }, '*');
} else {
console.warn('Vue 组件iframe 未初始化或数据无效,无法发送 FEED_DATA 消息。');
}
}
// 监听 props.data 的变化
watch(
() => props.data,
(newData) => {
// 确保新数据有效且 iframe 已初始化
if (newData && newData.length > 0 && isIframeInitialized.value) {
// 直接发送更新后的数据
sendDataToIframe(newData);
} else if (!isIframeInitialized.value) {
console.log('Vue 组件:数据已更改,但 iframe 尚未初始化。初始数据将在加载并初始化后发送。');
}
},
{
deep: true, // 保持深度监听,以防 data 内部变化
immediate: false, // 不在初始渲染时立即执行,等待 iframe 加载和初始化
},
);
// 可选:监听来自 iframe 的 WIDGET_READY 消息以实现更精确的控制
// onMounted(() => {
// window.addEventListener('message', handleIframeMessage);
// });
// onUnmounted(() => {
// window.removeEventListener('message', handleIframeMessage);
// });
// function handleIframeMessage(event: MessageEvent) {
// // 验证来源 event.origin
// if (event.source === iframeRef.value?.contentWindow && event.data.type === 'WIDGET_READY') {
// console.log('Vue 组件:收到来自 iframe 的 WIDGET_READY 消息');
// isIframeInitialized.value = true; // 确认 widget 已就绪
// // 现在可以安全地发送初始数据了
// if (props.data && props.data.length > 0) {
// sendDataToIframe(props.data);
// }
// }
// }
</script>
<template>
<iframe ref="iframeRef" :src="src" frameborder="0" allowfullscreen @load="onIframeLoad"></iframe>
</template>
<style scoped>
iframe {
width: 100%; /* 让 iframe 宽度充满容器 */
height: 100%; /* 让 iframe 高度充满容器 */
display: block; /* 避免可能的底部空白 */
border: none; /* 移除边框 */
}
</style>