软件系统定制开发无界(wujie)微前端实现及三种通信方式介绍

一、对比

之前,软件系统定制开发虽然实现了微前端的理念,软件系统定制开发但是也暴露出很多缺点,软件系统定制开发比如上讲到的四点:

  • 软件系统定制开发基于路由匹配,软件系统定制开发无法同时激活多个子应用,软件系统定制开发也不支持子应用保活
  • 改造成本较大,从 webpack、代码、路由等等都要做一系列的适配
  • css 沙箱无法绝对的隔离,js 沙箱在某些场景下执行性能下降严重
  • 无法支持 vite 等 ESM 脚本运行

而wujie利用来实现js沙箱能力,有效的解决了上述问题:

  • 组件方式来使用微前端

    不用注册,不用改造路由,直接使用无界组件,化繁为简

  • 一个页面可以同时激活多个子应用

    子应用采用 iframe 的路由,不用关心路由占用的问题

  • 天然 js 沙箱,不会污染主应用环境

    不用修改主应用window任何属性,只在iframe内部进行修改

  • 应用切换没有清理成本

    由于不污染主应用,子应用销毁也无需做任何清理工作

二、实现

这里主应用使用了vue3+vite,子应用使用了vue2+webpack。

​ 

1.主应用下载依赖(package.json)

yarn add wujie-vue3

2.主应用注册依赖(main.js)

import WujieVue from "wujie-vue3";

app.use(WujieVue);

3. 主应用使用wujie组件(main.vue)

<WujieVue name="micro" url="http://localhost:8087" >

4. 子应用修改跨域(webpack.dev.conf.js)

同。如果没有产生跨域,子应用甚至无需修改。

devServer: {

    headers: {

      "Access-Control-Allow-Origin": "*" // 开启应用间的跨域访问

    },

}

 这样便实现了wujie微前端的静态使用,那如何进行主子应用之间数据通信呢?

三、通信方式

先看一下主应用和子应用的代码。

主应用👇

  1. <script setup>
  2. import { ElMessage } from 'element-plus';
  3. import { ref } from 'vue'
  4. import wujie from 'wujie-vue3'
  5. const input = ref('')
  6. const emitInput = () => wujie.bus.$emit('input', input.value)
  7. const propsMethod = () =>
  8. {
  9. ElMessage.success('执行主应用方法成功')
  10. console.log(1111111, window.document.querySelector("iframe[name=micro]").contentWindow.globalMicroValue)
  11. }
  12. wujie.bus.$on('microEmit', (val) => input.value = val)
  13. window.globalMainValue = '我是主应用全局变量'
  14. </script>
  15. <template>
  16. <div class="container">
  17. <h1>main-vue3</h1>
  18. <el-input v-model="input" size="large" v-on:keyup.enter="emitInput">
  19. <template #append>
  20. <el-button @click="emitInput" icon="Promotion">
  21. </el-button>
  22. </template>
  23. </el-input>
  24. </div>
  25. <div class="container">
  26. <h1>micro-vue2</h1>
  27. <WujieVue name="micro" url="http://localhost:8087" :props="{data:'propsdata',method:{propsMethod}}">
  28. </WujieVue>
  29. </div>
  30. </template>

 子应用👇

  1. <template>
  2. <div class="container">
  3. <h1>{{data===''?'hi':data}}</h1>
  4. <el-button @click="doPropsData">获取父应用通过props传递的值</el-button>
  5. <el-button @click="doPropsMethod">执行父应用通过props传递的方法</el-button>
  6. <el-button @click="microEmit">向父应用传值</el-button>
  7. </div>
  8. </template>
  9. <script>
  10. export default {
  11. data ()
  12. {
  13. return {
  14. data: ''
  15. };
  16. },
  17. mounted ()
  18. {
  19. window.$wujie.bus.$on('input', (val) => this.data = val)
  20. window.globalMicroValue = '我是子应用全局变量'
  21. console.log(2222222, window.parent.globalMainValue)
  22. },
  23. // beforeDestroy ()
  24. // {
  25. // window.$wujie.bus.$off('input')
  26. // },
  27. methods: {
  28. doPropsMethod ()
  29. {
  30. window.$wujie.props.method.propsMethod()
  31. },
  32. doPropsData ()
  33. {
  34. this.data = window.$wujie.props.data
  35. },
  36. microEmit ()
  37. {
  38. window.$wujie.bus.$emit('microEmit', 'micro data')
  39. }
  40. }
  41. };
  42. </script>

1.props

通过props的方式,主应用既可以向子应用传递主应用的参数,还可以传递主应用的方法。

主应用在WuJieVue组件中使用,有点类似于vue的props。具体代码如下:

  1. <WujieVue name="micro" url="http://localhost:8087" :props="{data:'propsdata',method:{propsMethod}}">
  2. </WujieVue>

子应用则通过如下方式接收:

window.$wujie.props.data
window.$wujie.props.method.propsMethod()

2.window

主应用和子应用都可以通过挂载在window上定义全局变量的方式相互使用。

主应用定义全局变量:

window.globalMainValue = '我是主应用全局变量'

子应用定义全局变量:

 window.globalMicroValue = '我是子应用全局变量'

主应用使用子应用全局变量,其中name为WuJieVue中定义的子应用名称:

window.document.querySelector("iframe[name=micro]").contentWindow.globalMicroValue

子应用使用主应用全局变量:

window.parent.globalMainValue

3.eventBus

bus为wujie提供的一种去中心化的通信方式,即每个应用都是一个主体,主应用与子应用处于平等地位,主应用和子应用、子应用和子应用都可以通过这种方式方便的进行通信。包括监听、发送、取消监听三种。

  1. // 主应用监听事件
  2. bus.$on("事件名字", function (arg1, arg2, ...) {});
  3. // 主应用发送事件
  4. bus.$emit("事件名字", arg1, arg2, ...);
  5. // 主应用取消事件监听
  6. bus.$off("事件名字", function (arg1, arg2, ...) {});
  1. // 子应用监听事件
  2. window.$wujie?.bus.$on("事件名字", function (arg1, arg2, ...) {});
  3. // 子应用发送事件
  4. window.$wujie?.bus.$emit("事件名字", arg1, arg2, ...);
  5. // 子应用取消事件监听
  6. window.$wujie?.bus.$off("事件名字", function (arg1, arg2, ...) {});

四、子应用独立运行

如果不想让子应用单独运行,可以改造一下子应用的main.js文件,通过全局变量window.__POWERED_BY_WUJIE__判断该子应用是否是由主应用通过wujie启动,如果是,就执行wujie子应用的生命周期函数,完成挂载和销毁,如果不是,就不做任何操作,即可避免子应用可以单独打开的情况。

  1. import Vue from "vue";
  2. import App from "./App";
  3. import router from "./router";
  4. import store from "./store";
  5. import ElementUI from "element-ui";
  6. import "element-ui/lib/theme-chalk/index.css";
  7. Vue.use(ElementUI);
  8. // new Vue({
  9. // router,
  10. // store,
  11. // render: (h) => h(App),
  12. // }).$mount("#app");
  13. if (window.__POWERED_BY_WUJIE__) {
  14. let instance;
  15. window.__WUJIE_MOUNT = () => {
  16. instance = new Vue({ router, store, render: (h) => h(App) }).$mount("#app");
  17. };
  18. window.__WUJIE_UNMOUNT = () => {
  19. instance.$destroy();
  20. };
  21. } else {
  22. // new Vue({ router, store, render: (h) => h(App) }).$mount("#app");
  23. }
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发