频谱: iframe-page-comps/IframeSpectrogram.vue
This commit is contained in:
@ -0,0 +1,99 @@
|
||||
<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);
|
||||
// 使用 toRaw 获取原始数据对象
|
||||
iframeRef.value.contentWindow.postMessage({ type: 'FEED_DATA', payload: toRaw(payload) }, '*');
|
||||
} else {
|
||||
console.warn('Vue 组件:iframe 未初始化或数据无效,无法发送 FEED_DATA 消息。');
|
||||
}
|
||||
}
|
||||
|
||||
// 监听 props.data 的变化
|
||||
watch(
|
||||
() => props.data,
|
||||
(newData) => {
|
||||
console.log('Vue 组件: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 {
|
||||
border: none; /* 移除边框 */
|
||||
}
|
||||
</style>
|
72
src/components/iframe-page-comps/IframeSpectrogram.vue
Normal file
72
src/components/iframe-page-comps/IframeSpectrogram.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
// 不再需要 props 来接收数据
|
||||
|
||||
// 获取 iframe 的 DOM 引用
|
||||
const iframeRef = ref<HTMLIFrameElement | null>(null);
|
||||
|
||||
// iframe 的 src URL,指向 Spectrogram.html
|
||||
const src = computed(() => import.meta.env.BASE_URL + 'html-page/Spectrogram.html');
|
||||
|
||||
// 标记 iframe 是否已加载完成并已发送初始化指令
|
||||
const isIframeInitialized = ref(false);
|
||||
|
||||
// iframe 加载完成后的回调
|
||||
function onIframeLoad() {
|
||||
console.log('[🧩] 组件 (频谱图): iframe 已加载');
|
||||
// 发送初始化指令给 iframe
|
||||
if (iframeRef.value?.contentWindow) {
|
||||
console.log('[🧩] 组件 (频谱图): 向 iframe 发送 INIT_WIDGET 指令');
|
||||
// targetOrigin 设置为 '*' 为了简单,生产环境应指定确切来源
|
||||
// 可选:如果需要传递配置,可以在 INIT_WIDGET 消息中包含 config
|
||||
iframeRef.value.contentWindow.postMessage({ type: 'INIT_WIDGET' /*, config: props.config */ }, '*');
|
||||
isIframeInitialized.value = true; // 标记已发送初始化指令
|
||||
|
||||
// 发送初始数据(如果已有)
|
||||
// 稍微延迟发送,给 iframe 一点时间处理 INIT_WIDGET
|
||||
setTimeout(() => {
|
||||
// 初始数据将通过暴露的方法发送,这里不再处理
|
||||
console.log('[🧩] 组件 (频谱图): iframe 初始化完成,等待通过 ref 调用发送数据。');
|
||||
}, 0);
|
||||
} else {
|
||||
console.error('[🧩] 组件 (频谱图): 无法访问 iframe 的 contentWindow');
|
||||
}
|
||||
}
|
||||
|
||||
// 将数据发送到 iframe 的函数
|
||||
function sendDataToIframe(payload: Array<number>, time: string) {
|
||||
// 添加 time 参数
|
||||
// 确保 iframe 存在、其 contentWindow 可访问且已发送初始化指令
|
||||
if (iframeRef.value?.contentWindow && isIframeInitialized.value) {
|
||||
console.log('[🧩] 组件 (频谱图): 向 iframe 发送数据:', payload, '时间:', time);
|
||||
// 使用 toRaw 获取原始数据对象
|
||||
// 将时间和数据一起发送
|
||||
iframeRef.value.contentWindow.postMessage({ type: 'FEED_DATA', payload: toRaw(payload), time: time }, '*');
|
||||
} else {
|
||||
console.warn('[🧩] 组件 (频谱图): iframe 未初始化或数据无效,无法发送 FEED_DATA 消息。');
|
||||
}
|
||||
}
|
||||
|
||||
// 不再需要监听 props
|
||||
|
||||
// 可选:监听来自 iframe 的 WIDGET_READY 消息以实现更精确的控制 (与星座图类似)
|
||||
// onMounted(() => { ... });
|
||||
// onUnmounted(() => { ... });
|
||||
// function handleIframeMessage(event: MessageEvent) { ... }
|
||||
|
||||
// 暴露 sendDataToIframe 方法给父组件
|
||||
defineExpose({
|
||||
sendData: sendDataToIframe,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<iframe ref="iframeRef" :src="src" frameborder="0" allowfullscreen @load="onIframeLoad"></iframe>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
iframe {
|
||||
border: none; /* 移除边框 */
|
||||
width: 100%; /* 默认占满容器 */
|
||||
height: 100%; /* 默认占满容器 */
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user