micro-app微前端的入门与基础使用

470 阅读5分钟

老板要求本菜鸟学习微前端,希望将公司以后的项目部署成微前端,所以我也开始学习微前端,只是简单的小入门,先知道微前端具体是什么东西,之后随着项目的进行才能更深入了解。 前面提过了qiankun框架,现在公司使用的jeecg项目中自带的就是乾坤框架,但是朋友告诉我microApp会更好,于是又马不停蹄的开始学习micro。 注: 项目都是基于Vue。

上官网:cangdu.org/micro-app/d…

首先创建两个全新的脚手架,一个为基站,一个为子应用,分别使用 npm i @micro-zoe/micro-app --save在项目中下载好插件。

  1. 主应用中创建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

创建的路由主要是为了对应子应用,进而映射到基站的路由中。

  1. 在入口文件main.js中,引入micro,并启动;
import microApp from '@micro-zoe/micro-app';

microApp.start();
  1. 组件中引入子应用组件
<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属性就是传参啦,可以在子应用用查看。

  1. 现在到了子应用中,首选跟乾坤框架一样,在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文件中')
}

  1. 为了在基站中调用子类时不发生跨域,我们先提前配置一下vue.config.js。
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port:8083,
    headers: {
      'Access-Control-Allow-Origin': '*',
    }
  }
})

注: 8083是我自己配置的端口号,请务必要与基站组件的url对应。 这样就已经把子应用引入到基站中啦如下图所示。

1675234638044.jpg

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()方法进行监听,这样就可以拿到传递来的参数啦~~~

1675238360091.jpg

  1. 子应用向基站传递参数:

首先在子应用中定义好需要传递的参数:

<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)需要写死.

1675240404975.jpg

介绍完了类似父传子、子传夫的通信方式,我们再来一起学习一下全局数据通信。(全局数据通信会向基座应用和所有子应用发送数据,在跨应用通信的场景中适用。

首先我们介绍一下由基站发送数据,子应用接收数据:

(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>

1675242036320.jpg

介绍完基站发送全局通信,我们再来介绍一下子应用发送全局通信。 老生常谈,先介绍直接发送,直接接收: 子应用发送全局信息

<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的传参方法很类似,所谓万变不离其宗。 好啦,今天就先学到这里吧,等本菜鸟学习下一阶段,再来跟大家一起分享。