主应用iframe嵌入子页面模块, 子页面模块宽高根据主应用自适应, 并且完成适配

350 阅读7分钟

需求

搭建一个PC主应用系统, 采用Vue3+Webpack搭建, 已通过vw实现移动端适配(Vue Cli, Nuxt.js)&样式初始化实现了pc端的适配, 以兼容‌1280px~‌1920px的屏幕宽度, 设计稿的宽度为1920px, 系统某些页面需要嵌入多个第三方模块,那么需要实现的是:

1.嵌入的子页面必须和主系统尺寸完美融合(不能出现滚动条, 也不能有内容的截断)
2.子系统必须做适配, 因为需要兼容1280px~‌1920px的屏幕宽度, 如果主系统做了适配,子系统没做,在一个页面下不像是一个整体

基于需要实现的,得想下实际需要考虑的问题:

1.当系统进行第三方对接的时候, 第三方的页面一般是开发完了, 所以再做尺寸接入和适配的时候得考虑改动最小化
2.关于尺寸完美适配,这个比较统一, 适配的话, 存在以下的情况:
  a.第三方的模块原本做好了适配,那么解决好宽高尺寸问题后直接对接看看效果
  b.第三方如果是简单的html,专门为接入而开发,可以直接采用我建议的js代码做适配
  c.如果成品项目中去开发这个模块, 可以针对整个项目引入插件做适配,也可以采用单独的模块进行适配

具体实现

1.主应用

主系统实现适配, 并且可通过iframe嵌入子系统, 定义设计稿中子模块的宽高

Jul-21-2025 15-04-52.gif

<div class="son-system-example">
   <Iframe iframeUrl="http://127.0.0.1:5500/index.html" />
</div>

.son-system-example {
   width: 425px;
   height: 220px;
}

由于主系统采用了postcss-px-to-viewport插件适配, 所以此宽高会根据视宽自动调整, 适配文章参考vw实现移动端适配(Vue Cli, Nuxt.js)&样式初始化, 其中将750改成1920即可

主应用已经定义了子模块的大小, 并且实现了适配, 可以根据gif看到通过拉大浏览器视宽, 文字也在变大

2.子应用(第三方链接,第三方模块)
2.1 模拟子应用开发过程(无框架.html文件)

以简单的.html文件为例, 模拟宽高为425*220的第三方模块, 因为第三方系统是开发完再进行对接,或者开发完过很长一段时间再进行对接, 所以会按照设计稿写死宽高进行开发

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <div class="son-system">
    子模块文案子模块文案子模块文案子模块文案子模块文案子模块文案子模块文案子模块文案
    子模块文案子模块文案子模块
  </div>
  <style>
    html, body {
      padding: 0;
      margin: 0;
    }
    .son-system {
      width: 425px;
      height: 220px;
      background-color: yellow;
      border: 1px solid red; /*用于测试宽高是否在主应用中完整显示*/
      box-sizing: border-box; 
      font-size: 30px; /*后续用于测试自适应*/
    }
  </style>
</head>
<body>
</body>
</html>

wecom-temp-a17c203ed9f0a7bdba8217ee6da26d5c.png

如果直接接入的效果:

Jul-21-2025 17-50-53.gif

以上会出现两个问题, 第一个就是内容超出, 第二个内容没有适配屏幕宽度变化

先解决第一个问题,想要内容宽高与父元素保持一致,第一种是子应用不设置固定宽高, 宽高100%. 第二种是直接设置的宽高, 但是和主应用同等的适配方案, 这样也可以达到要求, 我们先采用第一种

2.2 子页面模块宽高根据主应用iframe宽高设定

设置子应用宽度100%, 在上面的代码中新增和覆盖:

    html, body {
      width: 100%;
      height: 100%; 
    }
    .son-system {
      width: 100%;
      height: 100%;
    }

完整代码:

    html, body {
      padding: 0;
      margin: 0;
      width: 100%; /*新增*/
      height: 100%; /*新增*/
    }
    .son-system {
      width: 100%; /*覆盖*/
      height: 100%; /*覆盖*/
      background-color: yellow;
      border: 1px solid red; /*用于测试宽高是否在主应用中完整显示*/
      box-sizing: border-box; 
      font-size: 30px; /*后续用于测试自适应*/
    }

以上要注意的是:
a.当html, body, 以及你的模块(.son-system)设置了100%, 仍然做不到以下这种效果,说明在模块上层,还有元素需要设置宽高为100%
b.由于子应用单独运行, 宽高已经设置了100%, 所以不能采用全屏的模式去看,需要设置开发者工具里面的视口宽度为设计稿宽度(例子中的425*220)
c.为了减少子应用本身的内容就存在溢出, 截断等或者不必要的padding,可以直接用 border: 1px solid red; box-sizing: border-box; 进行测试,确认后进行删除,以减少对接时间
d. 如果采用a的方式设置,模块(.son-system)的父级有很多层,那岂不是每层都要设置, 所以可以采用固定宽高(加与主应用同样的适配方式)实现, 后续会提到

Jul-22-2025 10-48-32.gif

下面是主应用的效果,当不同的设备宽度, 子应用和宽高和iframe给的宽高保持一致, 但是子应用的内容文字并没有变化, 这也是我们接下来需要解决的问题

Jul-22-2025 11-25-16.gif

2.3 子应用做内容适配(完全为接入创建的html页面)

2.3.1 如果第三方应用本身已经做了适配, 那么做好了宽高尺寸处理后, 直接找主应用进行接入, 无问题不用修改
2.3.2 如果专门为接入开发的一个html文件,没做适配, 可以采用下面我建议的适配方式, 比较简单

    html, body {
      font-size:calc(100vw/425*100); /*根据设计图的宽度而定 */
    }
    .son-system {
      font-size: 0.3rem; /*之前是30px, 改成rem, 往左移动2位小数 */
    }

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <div class="son-system">
    子模块文案子模块文案子模块文案子模块文案子模块文案子模块文案子模块文案子模块文案
    子模块文案子模块文案子模块
  </div>
  <style>
    html, body {
      padding: 0;
      margin: 0;
      width: 100%;
      height: 100%;
      font-size:calc(100vw/425*100); /*根据设计图的宽度而定*/
    }
    .son-system {
      width: 100%;
      height: 100%;
      background-color: yellow;
      border: 1px solid red; /*用于测试宽高是否在主应用中完整显示*/
      box-sizing: border-box; 
      font-size: 0.3rem;
    }
  </style>
</head>
<body>
</body>
</html>

Jul-22-2025 14-44-07.gif

Jul-22-2025 14-52-54.gif

以上可以看出, 不管是子应用尺寸可以根据iframe窗口而定, 内容也自适应窗口, 主应用也能完美的兼容模块内容, 主应用自有内容和子应用的内容适配保持一致

当子应用和主应用的适配方法基本一致时, 可以改成下面,固定的尺寸,也能实现, 这样可以减少我说的需要将所有父级改成100%的问题

企业微信截图_a6e93b5d-48df-4e13-98ec-a89c479203aa.png

2.4 子应用做内容适配(采用vue.js框架等)

2.4.1 假设第三方接到要提供给主应用链接的需求, 可能需要提供一个页面(对于主应用来说是模块),也可能是多个页面, 所以第三方很有可能直接在成品项目里面开白名单入口, 页面内容可以写在成品的项目里面, 这时候要考虑是对项目做全局的适配,还是做单独对着一部分进行适配, 如果是一个页面, 也可以采用上面我说的方案, 下面以vue.js项目为例:

html {
  height: 100%;
  font-size:calc(100vw/425*100);
}
<template>
  <div class="son">
    vue3项目测试一下
  </div>
</template>"
<style lang="scss" scoped>
  .son {
    width: 4.25rem;
    height: 2.20rem;
    background-color: yellow;
    border: 1px solid red;
    box-sizing: border-box;
    font-size: 0.24rem;
  }
</style>

Jul-22-2025 19-08-58.gif

2.4.2 如果是对整个项目进行适配 可以参考下面的方案, 主要还是使用postcss-px-to-viewport插件进行适配
vw实现移动端适配(Vue Cli, Nuxt.js)&样式初始化