核心逻辑
- vite和webpack不一致没有 webpack_public_path这个东西需要安装插件:vite-plugin-qiankun
- vite-plugin-qiankun 提供了一些公共方法可以直接使用避免了很多麻烦
代码
配置vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun'
import path from 'path'
//! useDevMode = true 时不开启热更新
const useDevMode = true;
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
qiankun('micro-org', {useDevMode})
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src') // 别名
}
},
server: {
port: 8081
}
})
main.ts文件
import { createApp } from 'vue'
import App from './App.vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import routes from './router'
import './public-path.js'
import {
renderWithQiankun,
qiankunWindow
} from 'vite-plugin-qiankun/dist/helper'
// 通过renderWithQiankun导出
import { mount, unmount, bootstrap, update } from './qiankun'
const initQianKun = () => {
// QiankunLifeCycle
renderWithQiankun({
mount,
bootstrap,
unmount,
update
})
}
const render = () => {
const router = createRouter({
history: createWebHashHistory(),
routes,
})
createApp(App).use(router).mount('#app')
}
qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render()
qiankun.ts
import { RouterHistory, createRouter, createWebHashHistory } from 'vue-router'
import { App, inject, InjectionKey, createApp } from 'vue'
import { QiankunProps } from 'vite-plugin-qiankun/dist/helper'
import routes from './router'
import MainApp from './App.vue'
let history: RouterHistory | null = null
let app: any = null
interface IGlobalState {
setGlobalState: (state: Record<string, any>) => void
onGlobalStateChange: (
func: (state: Record<string, any>, prev: Record<string, any>) => void
) => void
offGlobalStateChange: () => boolean
}
export const GlobalStateKey: InjectionKey<IGlobalState> = Symbol('')
// 全局调用乾坤框架消息方便进行消息传递
const createGlobalState = (props: any) => {
const globalState = {
install(app: App) {
app.config.globalProperties.$globalState = props
app.provide(GlobalStateKey, props)
},
}
return globalState
}
// vue3 use
const useGlobalState = () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return inject(GlobalStateKey)!
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
const mount = async (props: QiankunProps) => {
const { container } = props
history = createWebHashHistory('/org/')
const router = createRouter({
history,
routes,
})
app = createApp(MainApp)
if (container) {
app
.use(router)
.use(createGlobalState(props))
.mount(container.querySelector('#app'))
}
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
const unmount = async () => {
app.unmount()
if (history) {
history.destroy()
}
}
// bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
// 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
const bootstrap = async () => {
console.log('%c%s', 'color: green;', 'vue3.0 app bootstrap')
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
const update = async (props: any) => {
console.log('update props', props)
}
export { mount, unmount, bootstrap, update, useGlobalState }
特别注意
- public-path.js一定不能少
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
主应用:https://www.jianshu.com/p/48d74801b4c4
子应用链接:https://www.jianshu.com/p/6c3feb4c1062
vite子应用:https://www.jianshu.com/p/d364e6621b63