【D1n910】2020年qiankun根據(jù)官方文檔的使用&&學(xué)習(xí)記錄-API說明篇
正常操作,正常分析,大家好,我是 D1n910
以下內(nèi)容基本為手打的學(xué)習(xí)筆記,所以大部分內(nèi)容都會(huì)和
https://qiankun.umijs.org/zh
相同
其中會(huì)有不間斷的自己理解~
建議直接去看? qiankun 官方文檔?
加油加油
【qiankun官方文檔學(xué)習(xí)進(jìn)度 2/3】

API說明(資深調(diào)用API機(jī)器人蛋糕興奮起來了)
qiankun的 API 目前是分三種類型的
類型A:基于路由配置微應(yīng)用要用到的 API;
registerMicroApps(app, lifeCycles?)
start(opts?)
setDefaultMountApp(appLink)
runAfterFirstMounted(effect)
類型B:手動(dòng)加載微應(yīng)用要用到的 API;
loadMicroApp(app, configuration?)
prefetchApps(app, importEntryOpts?)
類型C:全局(全部微應(yīng)用)能夠同時(shí)用到的API。
addErrorHandler/removeErrorHandler
addGlobalUncaoughtErrorHandler(handler)
removeGlobalUncaughtErrorHandler(handler)
initGlobalState(state)
基于路由配置
適用于 route-base 場景。
通過將微應(yīng)用關(guān)聯(lián)到一些 url 規(guī)則的方式,當(dāng)瀏覽器url發(fā)生變化的時(shí)候,自動(dòng)加載相應(yīng)的微應(yīng)用。
registerMicroApps(apps, lifeCycles?)
參數(shù)(這里的類型主要用的是 TypeScript 的表示 —— 說起來,我之前學(xué)的 TypeScript 沒有學(xué)完)
apps - Array<RegistrableApp> - 必選,微應(yīng)用的一些注冊(cè)信息
lifeCycles -?LifeCycles- 可選,全局的微應(yīng)用生命周期鉤子
類型
RegistrableApp
· name - string- 必選,微應(yīng)用的名稱,微應(yīng)用之間必須確保唯一。(頁面上一般也不會(huì)有兩個(gè)重復(fù)的長得一模一樣的內(nèi)容嘛)
· entry - string | { scripts?: string[]; styles?: string[]; html?: string?}?- 必選,微應(yīng)用的入口
?????>>> 配置為字符串時(shí),表示微應(yīng)用的訪問地址。如果微應(yīng)用部署在二級(jí)目錄,則最后面的 /不可省略。例如,微應(yīng)用的訪問地址是:
https://qiankun.umijs.org/guide,那么 entry?應(yīng)該是 https://qiankun.umijs.org/guide/
? ? >>> 配置為對(duì)象時(shí),html?的值是微應(yīng)用的 html 內(nèi)容字符串,而不是微應(yīng)用的訪問地址。微應(yīng)用的 publicPath 將會(huì)被設(shè)置為 /。
·?container?- string | HTMLElement?- 必選,微應(yīng)用的容器節(jié)點(diǎn)的選擇器或者Element實(shí)例。如 container: '#root' 或 container: doument.querySelector('#root')。
·?activeRule?-?string | (location: Location) => boolean | Array<string | (location: Location) => boolean> - 必選,微應(yīng)用的激活規(guī)則。
? ? >>> 支持直接配置字符串或字符串?dāng)?shù)組,如?activeRule: '/app1'?或?activeRule:? ['/app1', '/app2'],當(dāng)配置為字符串時(shí)會(huì)直接跟 url 中的路徑部分做前綴匹配,匹配成功表明當(dāng)前應(yīng)用會(huì)被激活。
? ? >>> 支持配置一個(gè) acrive function 函數(shù)或一組 active function。函數(shù)會(huì)傳入當(dāng)前l(fā)ocation 作為參數(shù),函數(shù)返回 true 時(shí)表明當(dāng)前微應(yīng)用會(huì)被激活。如 location => location.pathname.startsWith('/app1')。
規(guī)則示例
'/app1'
? https://app.com/app1
? https://app.com/app1/anything/everything
?? https://app.com/app2
'/users/:userId/profile'
? https://app.com/users/123/profile
? https://app.com/users/123/profile/sub-profile/
???https://app.com/users//profile/sub-profile/
???https://app.com/users/profile/sub-profile/
'/pathname/#/hash'
? https://app.com/pathname/#/hash
? https://app.com/pathname/#/hash/route/nested
???https://app.com/pathname#/hash/route/nested
???https://app.com/pathname#/another-hash
['/pathname/#/hash', '/app1']
??https://app.com/pathname/#/hash/route/nested
??https://app.com/app1/anything/everything
???https://app.com/pathname/app1
???https://app.com/app2
瀏覽器 url 發(fā)生變化會(huì)調(diào)用 activeRule 里的規(guī)則, activeRule 任意一個(gè)返回 true 時(shí)表示該微應(yīng)用需要被激活。
loader - (loading: boolean) => void - 可選,loading 狀態(tài)發(fā)生變化時(shí)會(huì)調(diào)用的方法。
props - object - 可選,主應(yīng)用需要傳遞給微應(yīng)用的數(shù)據(jù)。
LifeCycles
全局的微應(yīng)用生命周期鉤子的類型
type Lifecycle = (app: RegistrableApp) => Promise<any>;
beforeLoad - Lifecycle | Array<Lifecycle> - 可選
beforeMount - Lifecycle | Array<Lifecycle> - 可選
afterMount - Lifecycle | Array<Lifecycle> - 可選
beforeUnmount?- Lifecycle | Array<Lifecycle> - 可選
afterUnmount -?Lifecycle | Array<Lifecycle> - 可選
用法
注冊(cè)微應(yīng)用的基礎(chǔ)配置信息。當(dāng)瀏覽器url發(fā)生變化時(shí),會(huì)自動(dòng)檢查每一個(gè)微應(yīng)用注冊(cè)的 activeRule 規(guī)則,符合規(guī)則的應(yīng)用將會(huì)被自動(dòng)激活。
示例
import { registerMicroApps } from 'qiankun';
registerMicroApps(
? ? [
? ? ? ? {
? ? ? ? ? ? name: 'app1',
? ? ? ? ? ? entry: '//localhost:8080',
? ? ? ? ? ? container: '#container',
? ? ? ? ? ? activeRule: '/react',
? ? ? ? ? ? props: {
? ? ? ? ? ??? ? ? name: 'kuitos',
? ? ? ? ? ??}
? ? ? ? }
? ?],
? {
? ? ? ? beforeLoad: app => console.log('before load', app.name),
??? ? ? beforeMount: [
? ? ? ??? ? ? ? app => console.log('before mount', app.name),
? ? ? ??],
? },
);
prefetch - boolean | 'all' | string[] | ((apps: RegistrableApp[])) => { criticalAppNames: string[]; minorAppsName: string[]?} - 可選,是否開啟預(yù)加載,默認(rèn)為 true。
配置為 true 則會(huì)在第一個(gè)微應(yīng)用 mount 完成后開始預(yù)加載其他微應(yīng)用的靜態(tài)資源;
配置為 'all' 則主應(yīng)用 start 之后即開始預(yù)加載所有微應(yīng)用靜態(tài)資源;
配置為 string[] 則會(huì)在第一個(gè)微應(yīng)用 mounted 后開始加載數(shù)組內(nèi)的微應(yīng)用資源;
配置為 function 則可以完全自定義應(yīng)用的資源加載時(shí)機(jī)(首屏應(yīng)用及次屏應(yīng)用)
sandbox - boolean | { strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean } - 可選,是否開啟沙箱,默認(rèn)為 true。
當(dāng)配置為 { strictStyleIslation: true?}?表示開啟嚴(yán)格的樣式隔離模式。這種模式下qiankun會(huì)為每個(gè)微應(yīng)用的容器包裹上一個(gè) shadow dom(這個(gè)相當(dāng)于瀏覽器自帶的原生組件,能夠保證樣式等是獨(dú)立出來的)節(jié)點(diǎn),從而確保微應(yīng)用的樣式不會(huì)對(duì)全局造成影響。
而除此以外,qiankun 還提供了一種實(shí)驗(yàn)性的方式來支持樣式隔離,當(dāng) experimentalStyleIsolation 被設(shè)置為 true 時(shí),qiankun 將會(huì)通過動(dòng)態(tài)改寫一個(gè)特殊的選擇器約束來限制css的生效范圍,應(yīng)用的樣式會(huì)按照如下模式改寫:
// 假設(shè)應(yīng)用名是 react16
.app-main {
? ? font-size: 14px;
}
div[data-qiankun-react16] .app-main {
? ? font-size: 14px;
}
注意:@keyframes, @font-face,@impprt, @page 將不被支持(i.e.不會(huì)被改寫)P.S:在目前的階段,該功能還不支持動(dòng)態(tài)的、使用<link />標(biāo)簽來插入外聯(lián)的樣式,但考慮在未來支持這部分場景。
singular - boolean | (app: RegistrableApp<any> => Promise<boolean>); - 可選,是否為單實(shí)例場景,單實(shí)例指的是同一時(shí)間只會(huì)渲染一個(gè)微應(yīng)用。默認(rèn)為 true。
fetch - Function - 可選,自定義的 fetch 方法
getPublicPath - (entry: Entry) => string - 可選,參數(shù)是微應(yīng)用的 entry 值。
getTemplate - (tpl:string) => string - 可選。
excludeAssetFilter - (assetUrl: string) => boolean - 可選,指定部分特殊的動(dòng)態(tài)加載的微應(yīng)用資源(css/js)不被 qiankun 挾持處理。
用法
啟動(dòng) qiankun
示例
import { start?} from 'qiankun';
start();
start(opts?)
參數(shù)
opts - Options (可選)
類型
Options
setDefaultMountApp(appLink)
參數(shù)
appLink - string - 必選
用法
設(shè)置主應(yīng)用啟動(dòng)后默認(rèn)進(jìn)入的微應(yīng)用。
示例
import { setDefaultMountApp?} from 'qiankun';
setDefaultMountApp('/homeApp');
????????runAfterFirstMounted(effect)
????????????參數(shù)
????????????effect - () => void - 必選
????????????用法
????????????第一個(gè)微應(yīng)用 mount 后需要調(diào)用的方法,這里可以開啟一些監(jiān)控或者埋點(diǎn)腳本。
????????????示例
????????????import { runAfterFirstMounted?} from 'qiankun';
????????????runAfterFirstMounted(() => startMonitor());
手動(dòng)加載微應(yīng)用
適用于需要手動(dòng) 加載/卸載? 一個(gè)微應(yīng)用的場景。
通常這種場景下微應(yīng)用是一個(gè)不帶路由的可獨(dú)立運(yùn)行的業(yè)務(wù)組件。比如是表單等等。
微應(yīng)用不宜拆分過細(xì),建議按照業(yè)務(wù)域來做拆分。業(yè)務(wù)關(guān)聯(lián)緊密的功能單元應(yīng)該做成一個(gè)微應(yīng)用,反之關(guān)聯(lián)不緊密的可以考慮拆分成多個(gè)微應(yīng)用。一個(gè)判斷業(yè)務(wù)關(guān)聯(lián)是否緊密的標(biāo)準(zhǔn):看這個(gè)微應(yīng)用與其他微應(yīng)用是否有頻繁的通信需求。如果有可能說明這兩個(gè)微應(yīng)用本身就是服務(wù)于同一個(gè)業(yè)務(wù)場景,合并成一個(gè)微應(yīng)用可能會(huì)更合適。
loadMircoApp(app, configuration?)
手動(dòng)直接加載微應(yīng)用。
【app】實(shí)際上就是前面registerMicroApps(apps, lifeCycles?) 的 apps類型。不需要activeRule屬性。
【configuration】這個(gè)和 registerMicroApps 的 configuration 的屬性是一樣的。
調(diào)用這個(gè)方法會(huì)返回 MicroApp - 微應(yīng)用示例。
有以下的屬性:
mount(): Promise<null>;
unmount(): Promise<null>;
update(customProps: object): Promise<any>;
getStatus(): | "NOT_LOASED" | "LOADING_SOURCE_CODE" | "NOT_BOOTStrapPED" | "BOOTStrapPING" | "NOT_MOUNTED" | "MOUNTING" | "MOUNTED" | "UPDATING" | "UNMOUNTING" | "SKIP_BECAUSE_BROKEN" | "LOAD_ERROR";
loadPromise: Promise<null>;
bootstrapPromise: Promise<null>;
mountPromise: Promise<null>;
unmountPromise: Promise<null>;
用法
手動(dòng)加載一個(gè)微應(yīng)用。
如果需要能支持主應(yīng)用手動(dòng) update 微應(yīng)用,需要微應(yīng)用 entry 再多導(dǎo)出一個(gè) update 鉤子:
export async function mount(props) {
????renderApp(props);
}
// 增加 update 鉤子以便主應(yīng)用手動(dòng)更新微應(yīng)用
export async function update(props) {
????renderPatch(props);
}
主應(yīng)用示例
import { loadMicroApp?} from 'qiankun';
import React from 'react';
class App extends? React.Component {
????containerRef = React.createRef();
????microApp = null;
????// 初始化掛載
????componentDidMount() {
????????this.microApp = loadMicroApp(
????????????{
? ? ????? ??????name: 'app1',
? ? ? ? ? ??????entry: '//localhost:1234',?
? ? ? ? ? ??????container: this.containerRef.current,
????????????????props: {
? ? ????????????????name: 'qiankun'
? ? ????????????}
? ? ? ? ? ???}
????????)
????}
????
????// 卸載微應(yīng)用
????componentWillUnmount() {
????????this.microApp.unmount();
????}
????// 更新微應(yīng)用
????componentDidUpdate() {
????????this.microApp.update({
????????????name: 'kuitos'
????????});
????}
????// React 的渲染方法
????render() {
????????return <div ref={this.containerRef}></div>
????}
}
prefetchApps(apps, importEntryOpts?)
用法:手動(dòng)預(yù)加載指定的微應(yīng)用靜態(tài)資源。僅手動(dòng)加載微應(yīng)用場景需要,基于路由自動(dòng)激活場景直接配置 prefetch 屬性即可
參數(shù)
apps - AppMetadata[] - 必選 - 預(yù)加載的應(yīng)用列表
importEntryOpts - 可選 - 加載配置。
去查了源代碼以后知道了,importEntryOpts 默認(rèn)值為一個(gè)空對(duì)象。
- 傳入為函數(shù)類型的時(shí)候,直接作為 `fetch` 使用
- 傳入為對(duì)象類型的時(shí)候,對(duì)象屬性用于解析 `html` 模版。如果不配置,模版內(nèi)置默認(rèn)屬性。詳見[import-html-entry 的 importHTML 函數(shù)](https://github.com/kuitos/import-html-entry/blob/master/src/index.js)
- fetch - `(url: string) => promise` - 可選,自定義的 fetch 方法, 用于獲取遠(yuǎn)端的腳本和樣式文件內(nèi)容。 - ?默認(rèn):瀏覽器 `fetch`
- getPublicPath - `(url: string) => publicPath:string` - 可選,用于獲取靜態(tài)資源 `publicPath`,將模板中外部資源為相對(duì)路徑的,轉(zhuǎn)換為絕對(duì)路徑。- 默認(rèn):當(dāng)前 `location.href` 為 `publicPath`。
- getDomain - `(url: string) => publicPath:string` - 可選,同 `getPublicPath` 。如果沒有提供 `getPublicPath` 參數(shù),則使用 `getDomain` ,兩者都沒有提供的時(shí)候,使用默認(rèn) `getPublicPath`。- 默認(rèn):無。
- getTemplate - `(html: string) => html:string` - 可選,用于在模板解析前,做一次處理。 - 默認(rèn):無處理
類型
AppMetadata
name - string - 必選 - 應(yīng)用名
entry - string |? { scripts?: string[]; styles?: string[]; html?: string?} - 必選,微應(yīng)用的 entry 地址
示例
import { prefetchApps?} from 'qiankun';
prefetchApps([ { name: 'app1', entry: '//locahost: 7001' }, { name: 'app2', entry: '//localhost:7002' } ])
addErrorHandler/removeErrorHandler
addGobalUncaughtErrorHandler(handler)
參數(shù)
handler - (...args: any[]) => void - 必選
用法
添加全局的未捕獲異常處理器。
示例
import { addGlobalUncaughtErrorHanlder } from 'qiankun';
addGlobalUncaughtErrorHandler(event => console.log(event));
removeGobalUncaughtErrorHandler(handler)
參數(shù)
handler - (...args: any[]) => void - 必選
用法
移除全局的未捕獲異常處理器。
示例
import { removeGlobalUncaughtErrorHandler?} from 'qiankun';
removeGlobalUncaughtErrorHandler(handler);
initGlobalState(handler)
參數(shù)
state - Record<string, any> - 必選
用法
定義全局狀態(tài),并返回通信方法,建議在主應(yīng)用使用,微應(yīng)用通過 props 獲取通信方法。
返回
MicroAppStateActions
- onGlobalStateChange: (callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void,在當(dāng)前應(yīng)用監(jiān)聽全局狀態(tài),有變更觸發(fā) callback。
設(shè)置 fireImmediately 為?true 可以初始化后立即觸發(fā) callback
- setGlobalState: (state: Record<string, any>)?=> boolean,按一級(jí)屬性設(shè)置全局狀態(tài),微應(yīng)用中只能修改已存在的一級(jí)屬性
- offGlobalStateChange: () => boolean,移除當(dāng)前應(yīng)用的狀態(tài)監(jiān)聽,微應(yīng)用 umount 時(shí)會(huì)默認(rèn)調(diào)用
示例
主應(yīng)用:
imprort { initGlobalState, MicroAppStateActions } from 'qiankun';
// 初始化 state
const? actions: MicroAppStateActions = initGlobalState(state);
actions.onGlobalStateChange((state, prev) => {
????console.log(stave, prev);
})
actions.setGlobalState(state);
actions.offGlobalStateChange();
微應(yīng)用:
// 從生命周期 mount 中獲取通信方法,使用方式和 master 一致
export funciotn mount(props) {
????props.onGlobalStateChange((state, prev) => {
????????console.log(state, prev);
????})
????props.setGlobalState(state);
}

本輪次的API說明文檔閱讀學(xué)習(xí),基本上掌握了 qiankun 暴露出來的 api(考驗(yàn)記憶力)??次臋n后,看到幾個(gè)錯(cuò)別字,提了一個(gè)pr,還合并進(jìn)去了,這里感覺非常好~大家要要多用用qiankun,然后多給開源項(xiàng)目共享~
本輪次學(xué)習(xí) END