老板要求本菜鸟学习微前端,希望将公司以后的项目部署成微前端,所以我也开始学习微前端,只是简单的小入门,先知道微前端具体是什么东西,之后随着项目的进行才能更深入了解。 前面提过了qiankun框架,现在公司使用的jeecg项目中自带的就是乾坤框架,但是朋友告诉我microApp会更好,于是又马不停蹄的开始学习micro。 注: 项目都是基于Vue。
首先创建两个全新的脚手架,一个为基站,一个为子应用,分别使用 npm i @micro-zoe/micro-app --save
在项目中下载好插件。
- 主应用中创建router.js文件(路由文件)
import Router from 'vue-router';
import MyPage from "@/components/HelloWorld.vue"
import Vue from 'vue'
Vue.use(Router)
const routes = [
{
path: '/mypage/*',
name: 'mypage',
component: MyPage
}
]
export default routes
创建的路由主要是为了对应子应用,进而映射到基站的路由中。
- 在入口文件main.js中,引入micro,并启动;
import microApp from '@micro-zoe/micro-app';
microApp.start();
- 组件中引入子应用组件
<template>
<div>
<h1>主应用</h1>
<micro-app name="app1" url="http://localhost:8083" baseroute="/mypage" :data="dataForChild"></micro-app>
</div>
</template>
<script>
export default {
data() {
return {
dataForChild: {
type: '传给子应用的数据'
}
}
},
created() {
if (window.__MICRO_APP_WNVIRONMENT__) {
console.log('微前端环境中');
}
}
}
</script>
可以看出引入的方式非常简单,类似于引入一个子组件,有name、url、baseroute属性,name属性就是给子应用命名,便于区分多个子应用,url即子应用的环境端口号,baseroute即基础路由,与路由文件中对应。data属性就是传参啦,可以在子应用用查看。
- 现在到了子应用中,首选跟乾坤框架一样,在src文件下创建public-path.js文件。
// __MICRO_APP_ENVIRONMENT__和__MICRO_APP_PUBLIC_PATH__是由micro-app注入的全局变量
if (window.__MICRO_APP_ENVIRONMENT__) {
// eslint-disable-next-line
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__;
console.info('微前端环境中--public-path.js文件中')
}
- 为了在基站中调用子类时不发生跨域,我们先提前配置一下vue.config.js。
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port:8083,
headers: {
'Access-Control-Allow-Origin': '*',
}
}
})
注: 8083是我自己配置的端口号,请务必要与基站组件的url对应。 这样就已经把子应用引入到基站中啦如下图所示。
ok,前面是简单的了解,将子应用展示到了基站中,现在我们来说一说组件的传参,如果微前端中没有传参功能的话,那么他也就没有存在的必要了,可以直接使用iframe。正因为它的强大的功能,我们才使用它。
首先我们先简单的介绍传参的方式:
1.基站向子应用传递参数
第一种: 在基站中data中传递,子应用中使用window.microApp.getData()获取,此方法不够灵活,无法产生联动,不建议使用。 基站代码:
<template>
<div>
<h1>主应用</h1>
<micro-app name="app1" url="http://localhost:8083" baseroute="/mypage" :data="dataForChild"></micro-app>
</div>
</template>
<script>
export default {
data() {
return {
dataForChild: {
type: '传给子应用的数据'
}
}
},
}
</script>
子应用
created() {
const data = window.microApp.getData();
console.log(data);
}
第二种: 在基站中使用microApp.setData()
传递,
<template>
<div>
<h1>主应用</h1>
<button @click="setData">基类给子类发送数据</button>
<micro-app name="app1" url="http://localhost:8083" baseroute="/mypage"></micro-app>
</div>
</template>
<script>
import microApp from '@micro-zoe/micro-app'
export default {
methods: {
setData() {
console.log(microApp);
microApp.setData('app1',{type: '1233333333333'})
}
}
}
</script>
我们可以看到setData中有两个参数,第一个参数为子应用的name名称,第二个就是需要传递的参数啦。接下来我们再看看子应用如何接受。
<script>
export default {
name: 'App',
mounted() {
window.microApp.addDataListener(this.dataListener)
},
methods: {
dataListener(data) {
console.log("来自基站的数据",data);
},
}
}
</script>
从代码中我们可以看到需要在子应用中定义一个方法,方法的自带的参数就是从基站传递来的参数,然后使用window.microApp.addDataListener()
方法进行监听,这样就可以拿到传递来的参数啦~~~
- 子应用向基站传递参数:
首先在子应用中定义好需要传递的参数:
<template>
<div id="app">
<button @click="setData">发送数据</button>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
setData() {
window.microApp.dispatch({type: '子应用发送的数据'})
}
}
}
</script>
然后就需要在基站中接受啦,官方提供了三种方法,我们来一起看一下,首先就是直接获取数据,
const childData = microApp.getData(appName)
这种方法就不多介绍了,实用性不大,基本上大家也不会使用,我们重点来介绍下面两种,第一个就类似于在子应用中接受基站的方法,我们一起看一下代码:
<template>
<div>
<h1>主应用</h1>
<micro-app name="app1" url="http://localhost:8083" baseroute="/mypage"></micro-app>
</div>
</template>
<script>
import microApp from '@micro-zoe/micro-app'
export default {
mounted() {
microApp.addDataListener('app1', this.dataListener);
},
methods: {
dataListener(data) {
console.log('来自子应用的数据', data);
},
}
}
</script>
看到代码不难发现相比于在子应用中接受基站的数据,这里的 microApp.addDataListener();
方法多了一个参数,其实不难理解,基站可能会存在很多子应用,所以需要一个name属性进行区分。
第二个办法就是自定义监听方法,对数据进行监听,我们看一下代码
<template>
<div>
<h1>主应用</h1>
<button @click="setData">基类给子类发送数据</button>
<micro-app name="app1" url="http://localhost:8083" baseroute="/mypage" @datachange="handleDatachange"></micro-app>
</div>
</template>
<script>
import microApp from '@micro-zoe/micro-app'
export default {
},
methods: {
handleDatachange(data) {
console.log("handleDatachange:",data.detail.data);
}
}
}
</script>
看到这个代码大家是不是很熟悉,就是Vue2中父传子,只不过这里的方法名称(dataChange
)需要写死.
介绍完了类似父传子、子传夫的通信方式,我们再来一起学习一下全局数据通信。(全局数据通信会向基座应用和所有子应用发送数据,在跨应用通信的场景中适用。
)
首先我们介绍一下由基站发送数据,子应用接收数据:
(1)直接获取数据(不推荐)
基站代码:
created() {
microApp.setGlobalData( {type: '基站发送全局数据 '})
},
子应用代码:
created() {
/**
* 全局数据
*/
const globalData = window.microApp.getGlobalData();
console.log('全局数据',globalData);
},
(2) 自定义监听方法,灵活性高(推荐)
这个办法相信大家已经非常熟悉了,没错还是监听方法,和接收基站数据一模一样!!!,但是需要修改接收的API函数 基站代码:
<template>
<div>
<h1>主应用</h1>
<button @click="setDatas">基类发送全局数据</button>
<micro-app name="app1" url="http://localhost:8083" baseroute="/mypage"></micro-app>
</div>
</template>
<script>
import microApp from '@micro-zoe/micro-app'
export default {
methods: {
setDatas() {
microApp.setGlobalData( {type: '基站发送全局数据 '})
}
}
}
</script>
子应用代码:
export default {
name: 'App',
mounted() {
window.microApp.addGlobalDataListener(this.dataListener)
},
methods: {
dataListener(data) {
console.log("来自全局的数据",data);
},
}
}
</script>
介绍完基站发送全局通信,我们再来介绍一下子应用发送全局通信。 老生常谈,先介绍直接发送,直接接收: 子应用发送全局信息
<template>
<div id="app">
<button @click="setDatas">发送全局数据</button>
</div>
</template>
<script>
export default {
methods: {
setDatas() {
window.microApp.setGlobalData({type: '子应用发送的全局数据'})
}
}
}
</script>
基站接收全局数据:
created() {
const globalData = microApp.getGlobalData() // 返回全局数据
console.log(globalData)
},
还有一种办法就是通过监听来接收啦:
<template>
<div>
<micro-app name="app1" url="http://localhost:8083" baseroute="/mypage"></micro-app>
</div>
</template>
<script>
import microApp from '@micro-zoe/micro-app'
export default {
mounted() {
microApp.addGlobalDataListener(this.getGlobalData)
},
methods: {
getGlobalData(data) {
console.log("基站接收全局数据:",data);
},
}
}
</script>
学习完所有通信方式,不难发现其实方法都差不多,跟vue2的传参方法很类似,所谓万变不离其宗。 好啦,今天就先学到这里吧,等本菜鸟学习下一阶段,再来跟大家一起分享。