📦 企业级 Vue3 项目 iframe 封装方案
一、封装统一的 Iframe 组件
文件:src/components/IframePage.vue
<template>
<div class="iframe-container">
<iframe
:src="computedSrc"
frameborder="0"
width="100%"
:height="height"
:sandbox="sandbox"
@load="onLoad"
ref="iframeRef"
></iframe>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
// 接收父组件传递的参数
const props = defineProps({
src: { type: String, required: true }, // iframe地址
height: { type: String, default: '100%' }, // iframe高度
token: { type: String, default: '' }, // 鉴权token(如需要)
sandbox: { type: String, default: 'allow-scripts allow-same-origin allow-forms allow-popups' }
})
const iframeRef = ref(null)
// 自动拼接 token,防止每次手动处理
const computedSrc = computed(() => {
if (!props.token) return props.src
const hasQuery = props.src.includes('?') ? '&' : '?'
return `${props.src}${hasQuery}token=${props.token}`
})
// 监听 iframe 加载事件
const onLoad = () => {
console.log('iframe 加载完成:', computedSrc.value)
// 你可以在这里做日志记录、上报监控、动态高度调整等
}
</script>
<style scoped>
.iframe-container {
width: 100%;
height: 100%;
position: relative;
}
iframe {
display: block;
border: none;
}
</style>
二、配合 Vue Router 动态路由使用
举例场景:部分菜单为嵌入第三方系统
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Layout from '@/layout/Layout.vue'
const routes = [
{
path: '/',
component: Layout,
children: [
{ path: '', name: 'Home', component: () => import('@/views/Home.vue') },
// 嵌入 iframe 菜单
{
path: '/bi-report',
name: 'BiReport',
meta: { title: 'BI报表系统' },
component: () => import('@/views/IframeWrapper.vue'),
props: { src: 'https://third-party.bi.com/report' }
}
]
}
]
export default createRouter({
history: createWebHistory(),
routes
})
三、封装通用 iframe 容器页
文件:src/views/IframeWrapper.vue
<template>
<div class="page-wrapper">
<IframePage :src="src" height="100vh" />
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
import IframePage from '@/components/IframePage.vue'
// 允许通过路由传参
const route = useRoute()
const src = route?.params?.src || route?.props?.src || ''
</script>
<style scoped>
.page-wrapper {
padding: 16px;
background: #fff;
height: 100%;
}
</style>
四、配合权限控制
假设你的权限控制已经封装好,使用时:
<IframePage
v-if="hasPermission('report:view')"
src="https://third-party.bi.com/report"
height="100vh"
/>
五、进阶:支持全局动态嵌入 iframe
如果未来你做微前端 or SaaS 多系统整合,可以考虑 iframe 动态管理:
- 配置表管理 iframe 菜单
- 后端动态下发 URL
- 支持多系统登录态隔离、传参
例如:
[
{
"name": "ERP系统",
"path": "/erp",
"src": "https://erp.xxx.com"
},
{
"name": "报表中心",
"path": "/report",
"src": "https://bi.xxx.com"
}
]
前端路由动态生成 iframe 页面。
✅ 核心优势总结
- ✅ 统一 iframe 组件封装
- ✅ 兼容权限控制
- ✅ 支持 Token 拼接、沙箱隔离
- ✅ 动态路由可复用
- ✅ 企业项目通用架构