基于umijs/plugin-qiankun 的微前端 配置(vue+umi)
qiankun + 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 消费数据
更多推荐
已为社区贡献2条内容
所有评论(0)