# 六.其他功能(微前端)
前言
使用乾坤开发一套由 Vue3.x 基座、Vue3.x 子项目、React 子项目组成的微前端项目
# 1.创建项目
在 micro 文件夹下创建 3 个项目
├── micro
├── base # 作为微前端的基座(vue3.x技术栈)
├── sub1 # 作为微前端的子项目sub1(vue3.x技术栈)
├── sub2 # 作为微前端的子项目sub2(react17.x技术栈)
1
2
3
4
2
3
4
# 2.配置基座
配置入口文件
// src/main.js
import { createApp } from "vue"
import App from "./App.vue"
import router from "./router"
import store from "./store"
import ElementPlus from "element-plus"
import "element-plus/dist/index.css"
import { registerMicroApps, start } from "qiankun"
import microApps from "./micro-app"
const app = createApp(App)
app.use(ElementPlus)
app.use(store).use(router).mount("#app")
const config = {
// 挂载前回调
beforeLoad: [
(app) => {
console.log("beforeload", app)
},
],
// 挂载后回调
beforeMount: [
(app) => {
console.log("beforeMount", app)
},
],
// 卸载后回调
afterUnmount: [
(app) => {
console.log("afterMount", app)
},
],
}
registerMicroApps(microApps(ElementPlus), config)
start({
prefetch: false,
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
配置子项目
// src/micro-app.js
const microApps = [
{
name: "sub1",
entry: "http://localhost:5501",
activeRule: "sub1",
container: "#sub1",
props: {
data: "来自基座的数据1",
fns: [
function LOGOUT_(data) {
alert("父应用返回信息:" + data)
},
],
},
},
{
name: "sub2",
entry: "http://localhost:5052",
activeRule: "sub2",
container: "#sub2",
props: {
data: "来自基座的数据2",
fns: [
function LOGOUT_(data) {
alert("父应用返回信息:" + data)
},
],
},
},
]
const apps = (ui) =>
microApps.map((item) => {
item.props.ui = ui
return {
...item,
// props: {
// routerBase: item.activeRule,
// },
}
})
export default apps
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
配置路由
// src/router/index.js
import { createRouter, createWebHistory } from "vue-router"
import Home from "../views/Home.vue"
const routes = [
{
path: "/",
redirect: "/base",
},
{
path: "/base",
name: "Home",
component: Home,
},
{
path: "/base/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue"),
},
]
const router = createRouter({
base: "/base",
history: createWebHistory(),
routes,
})
export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 3.配置 sub1
配置入口文件
// src/main.js
import { createApp } from "vue"
import App from "./App.vue"
import router from "./router"
import store from "./store"
let app = null
function render(props = {}) {
const { container } = props
console.log(container)
app = createApp(App)
app.use(store)
app.use(router)
app.mount("#vue")
}
if (window.__POWERED_BY_QIANKUN__) {
window.__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
console.log("1111111111", window.__webpack_public_path__)
} else {
console.log("2222222222")
render()
}
export async function bootstrap(props) {
console.log(props)
}
export async function mount(props) {
render(props)
app.use(props.ui)
// props.fns.forEach(fn => fn('加载完成'))
}
export async function unmount() {
app.unmount()
console.log(app, "app")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
配置路由
// src/router/index.js
import { createRouter, createWebHistory } from "vue-router"
import Home from "../views/Home.vue"
import About from "../views/About.vue"
const routes = [
{
path: "/",
redirect: "/sub1/about1",
},
{
path: "/sub1",
name: "Home",
component: Home,
},
{
path: "/sub1/about1",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: About,
},
]
const router = createRouter({
base: "/sub1",
history: createWebHistory(),
routes,
})
export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
配置 webpack
// vue.config.js
module.exports = {
devServer: {
port: 5501,
headers: {
"Access-Control-Allow-Origin": "*",
},
},
configureWebpack: {
output: {
library: "sub1",
libraryTarget: "umd",
},
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 4.配置 sub2
配置入口文件
// src/index.js
import React from "react"
import ReactDOM from "react-dom"
import "./index.css"
import App from "./App"
import reportWebVitals from "./reportWebVitals"
reportWebVitals()
function render(props = {}) {
const { container } = props
console.log(container)
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
)
}
if (window.__POWERED_BY_QIANKUN__) {
window.__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
console.log("1111111111", window.__webpack_public_path__)
} else {
console.log("2222222222")
render()
}
export async function bootstrap(props) {
console.log(props)
}
export async function mount(props) {
render(props)
// props.fns.forEach(fn => fn('加载完成'))
}
export async function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById("root"))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
配置 webpack
// config-overrides.js
module.exports = {
webpack: (config) => {
config.output.library = `sub2`
config.output.libraryTarget = "umd"
config.output.publicPath = "http://localhost:5052/"
return config
},
devServer: function (configFunction) {
return function (proxy, allowedHost) {
const config = configFunction(proxy, allowedHost)
config.headers = {
"Access-Control-Allow-Origin": "*",
}
return config
}
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 5.效果
TIP
可以使用通用的规则