qiankun子应用(vite)

核心逻辑

  1. vite和webpack不一致没有 webpack_public_path这个东西需要安装插件:vite-plugin-qiankun
  2. 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 }

特别注意

  1. 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容