微前端——Vue页面集成(iframe篇)
背景:最近公司有个需求,需要页面集成。这里我选的是iframe来实现,记录一下。
需求:有两个已经完成的项目,分别叫做A项目,B项目,现在需要将B项目的所有页面集成到A项目。
问题:由于两个都是独立的项目,并且都有自己的单独的登录入口。所以将B项目集成到A项目需要实现免登录。
解决方案:这里用到iframe来实现
实现免登录
1、在A项目中新建src/views/Integration/index.vue文件
<template>
<!-- 渲染B项目页面 :src这里的地址是B项目的页面地址 -->
<iframe id="iframe" :src="`http:127.0.0.1:8080/${url}`" frameborder="0" class="mainIframe"></iframe>
</template>
<script>
export default {
data(){
return {
iframe:null,
//B项目路由地址
routeList:[
{path:'/home',title:'首页'},
{path:'/about',title:'关于'}
]
}
},
//当A项目切换菜单时,匹配B项目的路由地址
computed:{
url(){
return this.routeList.find(item=>{return item.title===this.$route.meta.title})
}
},
mounted(){
this.initData()
},
methods:{
initData(){
this.iframe = document.getElementById('iframe')
this.iframe.onload = function(){
//A项目向B项目传值,第一个参数是传的值,第二个参数是目标源(A项目的地址)
that.iframe.contentWindow.postMessage('username','http:127.0.0.1:8080')
}
}
}
}
</script>
<style scoped>
.mainIframe{
width: 100%;
height: calc(100vh - 80px);
margin:20px;
}
</style>
2、在A项目中src/router/index.js 路径下配置对应路由菜单
import Vue from "vue";
import VueRouter from "vue-router";
import routes from "./routes";
Vue.use(VueRouter);
cosnt routes = [
{
name:"Home",
path:"/home",
meta:{title:'首页'}
component:()=>import('@/Integration/index')
},
{
name:"About",
meta:{title:'关于'}
path:"/about",
component:()=>import('@/Integration/index')},
]
const router = new VueRouter({
routes,
mode:"history"
})
export default router;
3、在B项目login.vue页面中
<script>
export default{
mounted(){
this.exemptLogin()
},
methods:{
exemptLogin(){
let that = this
window.addEventListener('message', function(e) {
if(e&&e.data && !e.data.type){
//免登录接口,拿到用户名生成token和用户信息返回
that.apiLogin({
username:e.data
}).then(res=>{
if(res.code==1000){
//这里将B项目原来登录入口,登录跳转之前获取数据的代码copy过来
that.$message.success('登录成功')
}
})
}
})
}
}
}
</script>
最后总结:
1、A项目向B项目通信传值
//第二个参数可以是*表示不限制目标源,可以是任何源向iframe发送消息。当iframe加载不同域的内容时,此时需要跨域通信,我们可以用*
//但是为了防止跨站脚本攻击,我们可以指定目标源。
iframe.contentWindow.postMessage("A项目需要传的值","A项目的域名地址")
2、B项目向A项目通信传值
window.parent.postMessage("B项目需要传的值","B项目的域名地址");
3、两个项目接收值,都可以使用addEventListener来监听
window.addEventListener('message', function(e) {
//打印e可以看到,传过来的值
}