Vue3 + TypeScript 实现 iframe 嵌入与通信的完整指南以及全屏弹窗方案

创建一个 IframeComponent 组件,用于嵌入 iframe

创建 src/components/IframeComponent.vue 文件:

html 复制代码
<template>
  <div class="iframe-container">
    <iframe ref="iframeRef" :src="src" :style="iframeStyle" @load="handleIframeLoad"></iframe>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, computed } from 'vue';

const props = defineProps({
  src: {
    type: String,
    required: true,
  },
  fullscreen: {
    type: Boolean,
    default: false,
  },
});

const iframeRef = ref<HTMLIFrameElement | null>(null);

const iframeStyle = computed(() => ({
  width: props.fullscreen ? '100vw' : '600px',
  height: props.fullscreen ? '100vh' : '400px',
  border: 'none',
}));

const handleIframeLoad = () => {
  console.log('Iframe loaded');
};

onMounted(() => {
  if (iframeRef.value) {
    iframeRef.value.addEventListener('load', handleIframeLoad);
  }
});
</script>

<style scoped>
.iframe-container {
  position: relative;
  overflow: hidden;
}
</style>

实现父子通信

创建 src/components/ParentComponent.vue 文件

html 复制代码
<template>
  <div class="parent-container">
    <h1>父组件</h1>
    <button @click="sendMessage">向Iframe发送消息</button>
    <button @click="toggleFullscreen">切换全屏</button>
    <IframeComponent
      ref="iframeComponentRef"
      :src="iframeSrc"
      :fullscreen="isFullscreen"
    />
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import IframeComponent from './IframeComponent.vue';

const iframeComponentRef = ref(null);
const iframeSrc = "https://example.com";
const isFullscreen = ref(false);

const sendMessage = () => {
  const iframeWindow = iframeComponentRef.value?.iframeRef?.contentWindow;
  if (iframeWindow) {
    iframeWindow.postMessage("来自父组件的问候", "*");
  }
};

const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value;
};
</script>

<style scoped>
.parent-container {
  padding: 20px;
}

button {
  margin-right: 10px;
  margin-bottom: 10px;
}
</style>

iframe 接收消息

在 iframe 加载的页面中,需要添加代码来监听来自父页面的消息。

创建 public/iframe.html 文件:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Iframe页面</title>
    <style>
      body {
        font-family: Arial, sans-serif;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        background-color: #f0f0f0;
      }
      .message-container {
        background-color: white;
        padding: 20px;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }
    </style>
  </head>
  <body>
    <div class="message-container">
      <h1>Iframe页面</h1>
      <p id="message">等待消息...</p>
    </div>
    <script>
      window.addEventListener("message", (event) => {
        console.log("收到来自父页面的消息:", event.data);
        document.getElementById(
          "message"
        ).textContent = `收到消息: ${event.data}`;
      });
    </script>
  </body>
</html>

使用组件

在 App.vue 中使用创建的 ParentComponent

html 复制代码
<template>
  <div id="app">
    <ParentComponent />
  </div>
</template>

<script lang="ts" setup>
import ParentComponent from './components/ParentComponent.vue';
</script>

iframe 内置弹框全屏问题解决方案

  1. iframe 宽高设置全屏,背景透明,border 设为 0,position 设置为 absolute top,left 设为0。
  2. 内嵌的 html 页面添加padding限制实际展示大小(具体值可由父级传到子级)。
  3. 内嵌页面 bodypadding。
  4. 监听内嵌页面的鼠标移动事件,和父级鼠标移动事件,判断鼠标位置确定用户操作范围,动态修改 iframe 范围外的其他元素层级,以便鼠标点击。
相关推荐
Csvn1 天前
OpenSpec 详细使用教程
前端
之歆1 天前
Day19_LESS 完全指南——从入门到工程实践
前端·css·less
云水一下1 天前
HTML5 从入门到精通:实战收官——从零搭建完整静态网站,综合运用所有知识
前端·html5
不总是1 天前
Windows 系统 Node.js 免安装版(zip)安装与配置教程(2026 最新)
前端·windows·node.js
冬奇Lab1 天前
每日一个开源项目(第105篇):Twenty - 跳出 Salesforce 的圈套,定义现代开源 CRM
前端·后端·开源
zhangyao9403301 天前
开发pc端时,表格的高度怎么设置才能铺满页面
前端·javascript·elementui
XinZong1 天前
实测OpenClaw虾淘:全民工具AI时代,冷门非工具类的Skill还能出圈吗?
javascript
kjs--1 天前
浏览器书签执行脚本
前端
烛衔溟1 天前
TypeScript 类的类型 —— 作为类型使用
javascript·ubuntu·typescript
之歆1 天前
Day16_JavaScript 轮播图与事件工程实战(下篇)
服务器·开发语言·前端·javascript·网络·性能优化