基于umijs/plugin-qiankun 的微前端 配置(vue+umi)

一,umijs/plugin-qiankun 特点

✔︎ 基于 qiankun
✔︎ 支持主应用和子应用都用 umi
✔︎ 支持通过 组件引入子应用
✔︎ 父子应用通讯
✔︎ 子应用运行时配置自定义 bootstrap()、mount() 和 unmount()
✔︎ 主应用、子应用联调
✔︎ 嵌套子应用
搭建页面
1, 主应用的搭建(使用umi配合内置的layout)
2,子应用搭建 (搭建了多个子应用(umi,vue)

二,主应用效果

在这里插入图片描述

三,主应用搭建

1,通过官方工具创建项目

yarn create @umijs/umi-app

注意: Umi 内置了以下别名:

 @,项目 src 目录
 @@,临时目录,通常是 src/.umi 目录
 umi,当前所运行的 umi 仓库目录
 react-router 和 react-router-dom,底层路由库,锁定版本,打包时所有依赖了他们的地方使用同一个版本
 react 和 react-dom,默认使用 16.x 版本,但如果项目里有依赖,会优先使用项目中依赖的版本

2,安装乾坤插件

npm i @umijs/plugin-qiankun -D 或者 yarn add @umijs/plugin-qiankun -D

3,修改配置,编辑 .umirc.ts, 例如:

import {
    
     defineConfig } from 'umi';
export default defineConfig({
    
    
  title: 'qiankun-demo', 
  favicon: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202012%2F04%2F20201204182229_e1a0a.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1653034439&t=1a24e65fd2a3d82a7390ca82cfad6041', // 修改浏览器上的icon
  nodeModulesTransform: {
    
    
    type: 'none',
  },
  // 内置 antd,目前内置版本是 ^4.0.0
  antd: {
    
    
    // dark: true,
    compact: true,
  },
  layout: {
    
    
    name: '乾坤微应用demo', //产品名称
    locale: false, //是否开启国际化,开启后路由配置的菜单名会被当做菜单名国际化的key
    logo:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202012%2F04%2F20201204182229_e1a0a.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1653034439&t=1a24e65fd2a3d82a7390ca82cfad6041'
  },
  routes: [
    {
    
     path: '/', component: '@/pages/index' },
    {
    
    
      path: '/dashboard',
      name: '显示方式',
      icon: 'dashboard',
      routes: [
        {
    
    
          path: '/dashboard/analysis',
          icon: 'AreaChartOutlined',
          name: '微应用直接显示',
          component: '@/pages/Dashboard/Analysis',
          // 微应用直接显示
          microApp: 'app2'
        },
        {
    
    
          path: '/dashboard/monitor',
          icon: 'DesktopOutlined',
          name: '主应用中嵌套MicroApp',
          // 在主应用中嵌套MicroApp
          component: '@/pages/Dashboard/Monitor',
        },
      ],
    },
    {
    
    
      path: '/app1',
      name: 'App1-umi子应用',
      icon: 'RadarChartOutlined',
      microApp: 'app1',
      props: {
    
    
        onClick: (event:number) => console.log(event),
        name: 'App1-umi子应用props',
        age: 1,
      },
    },
    {
    
    
      path: '/app2',
      name: 'APP2-umi子应用',
      icon: 'AreaChartOutlined',
      microApp: 'app2',
      props: {
    
    
        onClick: (event:any) => console.log(event),
        name: 'name: App2-umi子应用props',
        age: 1,
      },
    },
    {
    
    
      path: '/app-vue',
      name: 'vue子应用',
      icon: 'DotChartOutlined',
      microApp: 'qiankun-vue',
      props: {
    
    
        onClick: (event:any) => console.log(event),
        name: 'name: vue子应用props',
        age: 1,
      },
    },
    {
    
    
      path: '/vue-ayp',
      name: 'anyapeng',
      icon: 'smile',
      microApp: 'vue-ayp',
      props: {
    
    
        onClick: (event:any) => console.log(event),
        name: 'vue-ayp子应用props',
        age: 1,
      },
    },
  ],

  fastRefresh: {
    
    },//快速刷新(Fast Refresh),开发时可以保持组件状态,同时编辑提供即时反馈。
  qiankun: {
    
    
    master: {
    
    
      // 注册子应用信息
      apps: [
        {
    
    
          name: 'app1', // 唯一 id
          entry: '//localhost:8001', // html entry
        },
        {
    
    
          name: 'app2', // 唯一 id
          entry: '//localhost:8002', // html entry
        },
        {
    
    
          name: 'qiankun-vue', // 唯一 id
          entry: '//localhost:8888', // html entry
        },
        {
    
    
          name: 'vue-ayp', // 唯一 id
          entry: '//localhost:10000/', // html entry
        },
      ],
    },
  },
});

4oo,根目录下面建立 app.ts 。umi会自动找到暴露的useQiankunStateForSlave,传递路由配置的props参数
主应用:例如

import {
    
    useState} from 'react'
export  function useQiankunStateForSlave() {
    
    
    const [Number, setNumber] = useState({
    
    });
    return {
    
    
        Number,
      setNumber,
    };
  }

useModel路由、MicroApp通用的子应用接收:例如

import {
    
     useModel } from 'umi';
function MyPage() {
    
    
    //useModel('@@qiankunStateFromMaster')进行接收参数
    const masterProps = useModel('@@qiankunStateFromMaster');
    const {
    
     numberF, onChange } = masterProps
    const onAdd = () => {
    
    
        onChange()
    }
    return (
        <div>
            {
    
    numberF ? 
            <div>
            <Button onClick={
    
    () => {
    
     onAdd() }}>App1-umi本地应用点击加一</Button>
            <div>{
    
    numberF}</div>
           </div>
            : 
            'App1-umi本地应用无点击事件'
            }
        </div>
    )
}

四,子应用搭建

1,umi搭建的子应用

1,安装乾坤插件

npm i @umijs/plugin-qiankun -D 或者 yarn add @umijs/plugin-qiankun -D

2,配置app.ts ,没有app.ts的根目录创建一个app.ts,暴露qiankun对象

export const qiankun = {
    
    
    // 应用加载之前
    async bootstrap(props:object) {
    
    
      console.log('app1-umi子应用bootstrap1111',props);
    },
    // 应用 render 之前触发
    async mount(props:object) {
    
    
      console.log('app1-umi子应用mount1111',props);
  
    },
    // 应用卸载之后触发
    async unmount(props:object) {
    
    
      console.log('app1-umi子应用卸载11111',props);
  
    },
  };

3,对 .umirc.ts 进行配置

import {
    
     defineConfig } from 'umi';
export default defineConfig({
    
    
  nodeModulesTransform: {
    
    
    type: 'none',
  },
  routes: [
    {
    
     path: '/', component: '@/pages/index' },
    {
    
    
      path: '/app1/app2',
      name: 'vue',
      icon: 'DotChartOutlined',
      microApp: 'app2'
    },
  ],
  fastRefresh: {
    
    },
  qiankun: {
    
    
    slave: {
    
    }, // 必写
    master: {
    
    
      // 注册子应用信息
      apps: [
        {
    
    
          name: 'app2', // 唯一 id
          entry: '//localhost:8002', // html entry
        },
      ],
    },
  },
});

4,对 .env进行配置,进行端口限定

PORT=8001

2,vue搭建的子应用

1,安装乾坤插件

npm i @umijs/plugin-qiankun -D 或者 yarn add @umijs/plugin-qiankun -D

2, 配置vue.config.js

const {
    
     name } = require('./package');
const path = require('path')
module.exports = {
    
    
  devServer: {
    
    
    headers: {
    
    
      'Access-Control-Allow-Origin': '*',
    },
  },
 
  configureWebpack: {
    
    
    // 设置别名
    resolve: {
    
    
      alias: {
    
    
        "@": path.resolve(__dirname, "src"),
      },
    },
    output: {
    
    
      // 微应用的包名,这里与主应用中注册的微应用名称一致
      library: `${
      
      name}-[name]`,
      // 将你的 library 暴露为所有的模块定义下都可运行的方式
      libraryTarget: 'umd',
      // 按需加载相关,设置为 webpackJsonp_MicroAppPlugin 即可
      jsonpFunction: `webpackJsonp_vue`,
    },
  },
};

3, 在根目录 main.js 暴露qiankun 钩子

import Vue from 'vue'
import VueRouter from 'vue-router';
import  routes from './router.js';
console.log(routes,'routes')
// import store from './store';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'
Vue.use(ElementUI);
Vue.use(VueRouter)
Vue.config.productionTip = false

let router = null;
let instance = null;

function render(props = {
     
     }) {
    
    
  const {
    
     container } = props;
   router = new VueRouter({
    
    
    //  微应用配置路由 基础路径
    base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',
    mode: 'history',
    routes,
  });

  instance = new Vue({
    
    
    router,
    // store,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}


// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
    
    
  render();
}

export async function bootstrap() {
    
    
  console.log('vue子应用bootstrap');
}
export async function mount(props) {
    
    
  console.log('vue子应用mount', props);
  render(props);
}
export async function unmount(props) {
    
    
  console.log('vue子应用卸载', props);
  instance.$destroy();
  instance.$el.innerHTML = '';
  instance = null;
  router = null;
}

4,对 .env进行配置,进行端口限定

PORT=8001

五,父子应用通信

1,使用MicroApp 通信

1,父应用

mport {
    
     MicroApp } from 'umi';
import {
    
     useState } from 'react';
import {
    
     Button } from 'antd';

export default function IndexPage() {
    
    
  const [ age ,setAge] = useState(1)
  const onAdd = ()=>{
    
    
    setAge(age+1)
  }
  return (
    <div>
      <Button onClick ={
    
    ()=>{
    
    onAdd()}}>父应用增加年龄</Button>
        <div>{
    
    age}</div>
        {
    
    /* MicroApp 像props一样传参 */}
       <MicroApp name="vue-ayp" onChange={
    
    onAdd} age={
    
    age} />
    </div>
  );
}

2,子应用

import {
    
     useModel } from 'umi';

function MyPage() {
    
    
    //  useModel('@@qiankunStateFromMaster') 子应用可以在其内部全局拿到父应用传递过来的参数
    const masterProps = useModel('@@qiankunStateFromMaster');
    const {
    
     numberF, onChange } = masterProps
    const onAdd = () => {
    
    
        onChange()
    }
    return (
        <div>
            {
    
    numberF ? 
            <div>
            <Button onClick={
    
    () => {
    
     onAdd() }}>App1-umi本地应用点击加一</Button>
            <div>{
    
    numberF}</div>
           </div>
            : 
            'App1-umi本地应用无点击事件'
            }
        </div>
    )
}

2,使用路由传参 通信(官网的例子)

类似 react 中组件间通信的方案
主应用中配置 apps 时以 props 将数据传递下去

// src/app.js

export const qiankun = fetch('/config').then((config) => {
    
    
  return {
    
    
    apps: [
      {
    
    
        name: 'app1',
        entry: '//localhost:2222',
        props: {
    
    
          onClick: (event) => console.log(event),
          name: 'xx',
          age: 1,
        },
      },
    ],
  };
});

2,子应用在生命周期钩子中获取 props 消费数据

猜你喜欢

转载自blog.csdn.net/weixin_45701199/article/details/124351904