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 范围外的其他元素层级,以便鼠标点击。
相关推荐
老兵发新帖1 分钟前
pnpm常见报错解决办法
前端
Sonetto19998 分钟前
Nginx 反向代理,啥是“反向代理“啊,为啥叫“反向“代理?而不叫“正向”代理?它能干哈?
运维·前端·nginx
沐土Arvin8 分钟前
理解npm的工作原理:优化你的项目依赖管理流程
开发语言·前端·javascript·设计模式·npm·node.js
好_快24 分钟前
Lodash源码阅读-baseUniq
前端·javascript·源码阅读
不秃的开发媛25 分钟前
前端技术Ajax入门
java·开发语言·前端
牧羊狼的狼30 分钟前
React.memo 和 useMemo
前端·javascript·react.js
xixixin_38 分钟前
【uniapp】vue2 搜索文字高亮显示
java·服务器·前端·uni-app·交互·文字高亮
还是鼠鼠41 分钟前
Android移动应用开发入门示例:Activity跳转界面
android·前端·gitee·android studio·android-studio
不知疲倦的仄仄1 小时前
跨域 同源策略通俗讲解
前端·后端·spring·edge浏览器
珹洺1 小时前
Jsp技术入门指南【十】IDEA 开发环境下实现 MySQL 数据在 JSP 页面的可视化展示,实现前后端交互
java·运维·前端·mysql·intellij-idea·jsp