Vue3子应用在umi中qiankun接入

Vue3子应用在umi中qiankun接入

当项目比较庞大,集成平台之类的,需要耦合多种业务,那么采用微前端维护是比较合理的,这里介绍如何将vue子应用接入umi主应用,并实现子应用与主应用之间的通信。

一、子应用 Vite + vue3

安装vite插件

npm i -D vite-plugin-qiankun

配置 vite.config

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import qiankun from 'vite-plugin-qiankun'; // 引入适配器
 
export default defineConfig({
  plugins: [
    vue(),
    qiankun('subApp', { // 主应用登记的一模一样!
      useDevMode: process.env.NODE_ENV === "development" // 开发模式也要能上台排练
    })
  ],
  server: {
    port: 6104, // 端口,必须和主应用 `entry` 一致
    origin: 'http://localhost:6104' // 确保资源能找到回家的路
  },
  base: process.env.NODE_ENV === 'production'
    ? 'http://dx.test.vip/' // 完整的部署地址
    : '/', // 本地运行
});

改造main.ts

import { createApp } from "vue"
import App from "./App.vue"
import { setupRouter } from "./router/index"
import { setupStore } from "./store/index"
import { loadScopedIconfont } from "@/utils/iconfont"
import { renderWithQiankun, qiankunWindow } from "vite-plugin-qiankun/dist/helper"

import "@/styles/index.less"
import "@/components/MixTable/styles/table.less"

loadScopedIconfont({
  iconfontUrl: "//at.alicdn.com/t/c/font_2885052_dsy4qqlpgxs.css",
  subAppName: "test-web"
})

let app: any = null // 保存 Vue 应用实例

// 渲染逻辑
function renderStandaloneApp(container: any = null) {
  app = createApp(App)
  setupRouter(app, container ? "/subApp" : "/")
  setupStore(app)

  const rootContainer = container ? container.querySelector("#app") : "#app"
  app.mount(rootContainer)
}

// 判断独立渲染模式
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  renderStandaloneApp()
}

// Qiankun 生命周期钩子
renderWithQiankun({
  bootstrap() {
    console.log("subApp bootstrap")
  },
  mount(props) {
    console.log("subApp mount", props)
    renderStandaloneApp(props.container)
  },
  update(props) {
    console.log("subApp update", props)
  },
  unmount() {
    console.log("subApp unmount")
    app?.unmount()
    app = null
  }
})

路由注册根据子应用带上base

export const setupRouter = (app: App<Element>, base = "/") => {
  const router = createRouter({
    history: createWebHistory(base),
    routes
  })

  app.use(router)

  router.beforeEach(beforeRouter)
}

iconfont与主应用隔离

动态加载iconfont资源,重写iconfont的font-family,为每个icon添加子应用的class父级类包裹

export const loadScopedIconfont = async ({ iconfontUrl = "", subAppName = "" }) => {
  if (!iconfontUrl) return
  const response = await fetch(iconfontUrl)
  let cssText = await response.text()

  // 为所有 iconfont 相关的选择器添加命名空间
  cssText = cssText
    .replace(/(\.icon[^,{};]*)/g, `.${subAppName} $1`)
    .replace(/font-family: "iconfont"/g, `font-family: "${subAppName}-iconfont"`)

  const style = document.createElement("style")
  style.textContent = cssText
  document.head.appendChild(style)
}

在App.vue中用子应用确定的隔离class包裹路由

<div class="test-web">
  <router-view />
</div>

二、主应用 umijs

qiankun注册子应用

export default {
  qiankun: {
    master: {
      apps: [
        {
          name: 'subApp',
          entry: 'http://subApp.molsci.vip',
        },
      ],
    },
  }
};

路由注册子应用路由

export default [
  {
    path: '/',
    component: '@/components/Layout',
    routes: [
      {
        path: '/subApp/*',
        microApp: 'subApp',
      },
    ]
  }
]

向子应用传值

在app.tsx中导出useQiankunStateForSlave

export function useQiankunStateForSlave() {
  const [initAppState, setInitAppState] = React.useState<any>({
    _appName: 'Molsci',
  });

  return {
    initAppState,
    setInitAppState,
  };
}

三、主应用和子应用通信

Qiankun 提供了 <font style="color:rgb(77, 77, 77);">initGlobalState</font>传递初始参数

主应用传递

export function useQiankunStateForSlave() {
  const [initAppState, setInitAppState] = React.useState<any>({
    _appName: 'myApp',
  });

  return {
    initAppState,
    setInitAppState,
  };
}

子应用回传

renderWithQiankun({
  mount(props) {
    /** 监听主应用透传的state变化 */
    props.onGlobalStateChange(
      (newState, oldState) => {
        console.log('  Vue子应用监听到:', newState);
      },
      true // true 表示立刻用当前状态触发一次上面的回调
    );
 
    // 子应用更新主应用中的state
    function updateProjectLoading() {
      props.setGlobalState({
        loading: false // 只能更新 initialState 里已有的一级属性!
      });
    }
  },
});

四、子应用部署

1.Nginx配置

需要配置能跨域访问,才能保证主应用在不同域能拉取到子应用

server {
    listen 80;
    server_name dx.test.vip;

    location / {
        root E:/deng/mssk-web/test-web/dist;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;

        # 添加CORS头
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值