vue3+vite+qiankun

179 阅读2分钟

第一步 安装依赖

主应用
pnpm install qiankun
微应用
pnpm install vite-plugin-qiankun

第二步 主应用配置

src下创建qiankun.ts

```import type { MicroAppStateActions } from "qiankun";
import { initGlobalState, registerMicroApps, start } from "qiankun";

// 初始化 state
const state = {
  token: "r797355672jiofpopifh"
};
const actions: MicroAppStateActions = initGlobalState(state);

export function registerQiankunApps() {
  registerMicroApps(
    [
      {
        name: "qiankunApp", //微应用名称方便维护最好一致
        entry: "http://localhost:8849", // 微应用地址
        container: "#container", // 子应用挂在id
        activeRule: "/#/home", // 触发规则
        props: {
          // 传递参数
          nikcname: "我爱白菜",
          baseName: "/moral-education-manage"
        }
      }
    ],
    {
      beforeLoad: app => {
        console.log("正在加载应用:", app.name);
        return Promise.resolve();
      },
      beforeMount: app => {
        console.log("正在挂载应用:", app.name);
        return Promise.resolve();
      }
    }
  );
  // 启动微前端
  start({
    prefetch: "all", // 预加载
    sandbox: {
      strictStyleIsolation: false, // 严格样式隔离
      experimentalStyleIsolation: true // 开启沙盒模式
    }
  });
  // 父子通信
  actions.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    console.log("父", state, prev);
  });
  // 模拟请求
  setTimeout(() => {
    actions.setGlobalState({ ...state, age: "18" });
  }, 2000);
  // 关闭乾坤全局状态监听
  actions.offGlobalStateChange();
}

注意一定要在dom节点创建后再注册事件

<template>
  <div class="home card" id="container"></div>
</template>

<script setup lang="ts" name="home">
import { registerQiankunApps } from "@/qiankun";
import { onMounted } from "vue";
onMounted(() => {
  registerQiankunApps();
});
</script>

<style scoped lang="scss">
@import "./index";
</style>

第三步 微应用配置

在vite.config.ts中添加plugins

image.png image.png

修改main.ts文件

```import { createApp } from "vue";
import App from "./App.vue";
import "virtual:uno.css";
// reset style sheet
import "@/styles/reset.scss";
// CSS common style sheet
import "@/styles/common.scss";
// iconfont css
import "@/assets/iconfont/iconfont.scss";
// font css
import "@/assets/fonts/font.scss";
// element css
import "element-plus/dist/index.css";
// element dark css
import "element-plus/theme-chalk/dark/css-vars.css";
// custom element dark css
import "@/styles/element-dark.scss";
// custom element css
import "@/styles/element.scss";
// svg icons
import "virtual:svg-icons-register";
// element plus
import ElementPlus from "element-plus";
// element icons
// import * as Icons from "@element-plus/icons-vue";
// custom directives
import directives from "@/directives/index";
// vue Router
import router from "@/routers";
// vue i18n
import I18n from "@/languages/index";
// pinia store
import pinia from "@/stores";

// 导入 vite-plugin-qiankun 提供的工具函数
import { renderWithQiankun, qiankunWindow } from "vite-plugin-qiankun/dist/helper";

let app: any = null;

function render(props = {}) {
  const { container } = props;
  app = createApp(App);
  app.use(router);
  app
    .use(ElementPlus)
    .use(directives)
    .use(router)
    .use(I18n)
    .use(pinia)
    .mount(container ? container.querySelector("#app") : "#app");
}

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  render();
}
renderWithQiankun({
  mount(props) {
    console.log("参数", props);

    props.onGlobalStateChange((state, prev) => {
      // state: 变更后的状态; prev 变更前的状态
      console.log("子", state, prev);
 });
    render(props);
  },
  bootstrap() {
    console.log("--bootstrap");
  },
  update(props) {
    console.log("--update", props);
  },
  unmount() {
    console.log("--unmount");
    app?.unmount();
  }
});

第四步 完成配置

通过主应用actions.setGlobalState向微应用传递参数,微应用向主应用传递参数也用props.setGlobalState,如果不需要接收 // 关闭乾坤全局状态监听 actions.offGlobalStateChange();