基于qiankun的微前端最佳實(shí)踐-通信篇(Vuex)

大家好~~

在開始介紹 qiankun 的應(yīng)用通信之前丽啡,我們需要先了解微前端架構(gòu)如何劃分子應(yīng)用辱匿。

在微前端架構(gòu)中刃永,我們應(yīng)該按業(yè)務(wù)劃分出對(duì)應(yīng)的子應(yīng)用货矮,而不是通過(guò)功能模塊劃分子應(yīng)用。這么做的原因有兩個(gè):

  1. 在微前端架構(gòu)中斯够,子應(yīng)用并不是一個(gè)模塊囚玫,而是一個(gè)獨(dú)立的應(yīng)用,我們將子應(yīng)用按業(yè)務(wù)劃分可以擁有更好的可維護(hù)性和解耦性读规。
  2. 子應(yīng)用應(yīng)該具備獨(dú)立運(yùn)行的能力抓督,應(yīng)用間頻繁的通信會(huì)增加應(yīng)用的復(fù)雜度和耦合度。

綜上所述束亏,我們應(yīng)該從業(yè)務(wù)的角度出發(fā)劃分各個(gè)子應(yīng)用铃在,盡可能減少應(yīng)用間的通信,從而簡(jiǎn)化整個(gè)應(yīng)用碍遍,使得我們的微前端架構(gòu)可以更加靈活可控定铜。

上面的這段話是引自這篇好文,這篇文章中主要介紹了兩種主應(yīng)用和微應(yīng)用的通信方式

第一種是 qiankun 官方提供的通信方式 - Actions 通信怕敬,適合業(yè)務(wù)劃分清晰揣炕,比較簡(jiǎn)單的微前端應(yīng)用,一般來(lái)說(shuō)使用第一種方案就可以滿足大部分的應(yīng)用場(chǎng)景需求东跪。

第二種是基于 redux 實(shí)現(xiàn)的通信方式 - Shared 通信畸陡,適合需要跟蹤通信狀態(tài),子應(yīng)用具備獨(dú)立運(yùn)行能力虽填,較為復(fù)雜的微前端應(yīng)用丁恭。

我寫這篇博客的主要原因是探究主應(yīng)用和多個(gè)微應(yīng)用之間如何使用Vuex來(lái)進(jìn)行狀態(tài)管理,這其實(shí)是對(duì)于上面通信方式中斋日,第二種方式的補(bǔ)充牲览。

場(chǎng)景

項(xiàng)目現(xiàn)狀:

  1. 主應(yīng)用是Vue技術(shù)棧,使用Vuex進(jìn)行狀態(tài)管理
  2. 多個(gè)微應(yīng)用也是Vue技術(shù)棧桑驱,并且都可能使用Vuex進(jìn)行狀態(tài)管理

想要解決的問(wèn)題:

  1. 主應(yīng)用與微應(yīng)用的通信
  2. 微應(yīng)用之間的通信

通信方式的選擇:

  1. qiankun 官方提供的通信方式 - Actions 通信竭恬。

    優(yōu)點(diǎn):

    • 使用簡(jiǎn)單;
    • 官方支持性高熬的;
    • 適合通信較少的業(yè)務(wù)場(chǎng)景;

    缺點(diǎn):

    • 子應(yīng)用獨(dú)立運(yùn)行時(shí)赊级,需要額外配置無(wú) Actions 時(shí)的邏輯押框;
    • 子應(yīng)用需要先了解狀態(tài)池的細(xì)節(jié),再進(jìn)行通信理逊;
    • 由于狀態(tài)池?zé)o法跟蹤橡伞,通信場(chǎng)景較多時(shí)盒揉,容易出現(xiàn)狀態(tài)混亂、維護(hù)困難等問(wèn)題兑徘;
  2. 使用Vuex進(jìn)行狀態(tài)管理

    優(yōu)點(diǎn):

    • 子應(yīng)用無(wú)法隨意污染主應(yīng)用的狀態(tài)池刚盈,只能通過(guò)主應(yīng)用暴露的 shared 實(shí)例的特定方法操作狀態(tài)池,從而避免狀態(tài)池污染產(chǎn)生的問(wèn)題挂脑。
    • 子應(yīng)用將具備獨(dú)立運(yùn)行的能力

    缺點(diǎn):

    暫時(shí)沒(méi)有想到藕漱。。崭闲。肋联。

核心思想

Vuex通信Store共享.jpg

主要就是在做微前端集成時(shí),將主應(yīng)用的store共享給所有微應(yīng)用刁俭,針對(duì)不同微應(yīng)用可以進(jìn)行模塊化設(shè)置橄仍,這樣使得共享的state更加易于管理。

具體實(shí)現(xiàn)(微應(yīng)用原本就沒(méi)有使用Vuex進(jìn)行狀態(tài)管理)

step1:主應(yīng)用向微應(yīng)用傳遞store實(shí)例牍戚。

registerMicroApps(
      [
          {
              name: "chai-project",
              entry: "http://localhost:8080",
              container: '#yourContainer',
              activeRule: "/chaiQiankunTest/ffff",
              props: {
                store //共享主應(yīng)用的store實(shí)例
              }
          }
      ],
      {
          beforeLoad: [
              app => {
                  console.log("before load", app);
              }
          ], // 掛載前回調(diào)
          beforeMount: [
              app => {
                  console.log("before mount", app);
              }
          ], // 掛載后回調(diào)
          afterUnmount: [
              app => {
                  console.log("after unload", app);
              }
          ] // 卸載后回調(diào)
      }
    )

step2:微應(yīng)用使用主應(yīng)用共享的store實(shí)例

針對(duì)第一種情況侮繁,就是在入口文件中引入vuex,并使用該插件如孝,進(jìn)而在創(chuàng)建vue實(shí)例的時(shí)候鼎天,傳入主應(yīng)用共享的store實(shí)例。

import Vuex from 'vuex'
Vue.use(Vuex);
function render (props) {
  const store = props.store;
  // 在 render 中創(chuàng)建 VueRouter暑竟,可以保證在卸載微應(yīng)用時(shí)斋射,移除 location 事件監(jiān)聽,防止事件污染
  router = new Router({
    // 運(yùn)行在主應(yīng)用中時(shí)但荤,添加路由命名空間 /chaiQiankunTest/ffff
    base: window.__POWERED_BY_QIANKUN__ ? 'chaiQiankunTest/ffff' : '/',
    mode: 'history',
    routes
  });

  // 掛載應(yīng)用
  instance = new Vue({
    router,
    store,//主應(yīng)用共享的store實(shí)例
    render: (h) => h(App)
  }).$mount('#app');
}

step3:驗(yàn)證主應(yīng)用和微應(yīng)用之間是否可以完成通信罗岖,狀態(tài)同步。

驗(yàn)證的思路就是

(1)在主應(yīng)用和微應(yīng)用的頁(yè)面上添加改變同一個(gè)state的方法腹躁,并且利用computed實(shí)時(shí)顯示該state的狀態(tài)值桑包。

(具體的實(shí)現(xiàn)代碼這里就不詳細(xì)給出)

驗(yàn)證用例主要是

(1)點(diǎn)擊主應(yīng)用按鈕,修改state值之后纺非,主應(yīng)用和微應(yīng)用的頁(yè)面上都實(shí)時(shí)觸發(fā)computed屬性哑了,展示最新狀態(tài)值

(2)點(diǎn)擊微應(yīng)用按鈕,修改state值之后烧颖,主應(yīng)用和微應(yīng)用的頁(yè)面上都實(shí)時(shí)觸發(fā)computed屬性弱左,展示最新狀態(tài)值

驗(yàn)證的結(jié)果

不論是點(diǎn)擊主應(yīng)用的按鈕,還是點(diǎn)擊微應(yīng)用的按鈕炕淮,主應(yīng)用的computed屬性成功被觸發(fā)拆火,微應(yīng)用始終未能正常監(jiān)聽到狀態(tài)值得改變,computed屬性從未被觸發(fā)。

這里查閱了蠻多的資料们镜,沒(méi)能看到有大神對(duì)qiankun使用Vuex的經(jīng)驗(yàn)總結(jié)(這里也發(fā)現(xiàn)自己有點(diǎn)過(guò)于依賴網(wǎng)絡(luò)搬磚币叹,有些問(wèn)題積極思考是能夠找到答案的)

step4:bug修復(fù)

微應(yīng)用的computed始終沒(méi)有被觸發(fā),底層原因就是其依賴屬性this.$store.state.count是非相應(yīng)式的模狭,這會(huì)導(dǎo)致難以觸發(fā)颈抚。

computed: {
    childCount: {
      get (){
        return this.$store.state.count;
      }
    }
}

Vuex正常使用的時(shí)候,所有的狀態(tài)值都是響應(yīng)式的嚼鹉,可以直接用于Vue頁(yè)面之中贩汉,但是這里是非響應(yīng)式的,導(dǎo)致這個(gè)的原因其實(shí)十分簡(jiǎn)單反砌。這里的store實(shí)例是由主應(yīng)用傳遞過(guò)來(lái)的雾鬼,store中的狀態(tài)對(duì)于主應(yīng)用的Vue實(shí)例而言是親兒子,是響應(yīng)式的宴树,在微應(yīng)用中策菜,雖然可以使用共享store實(shí)例中的commit方法,但是對(duì)于微應(yīng)用的Vue實(shí)例而言酒贬,不是親兒子又憨,是非響應(yīng)式的,這樣分析之后锭吨,解決方案就十分明確:

在微應(yīng)用中將共享的store實(shí)例進(jìn)行響應(yīng)式設(shè)置蠢莺,這是Vue現(xiàn)有的API方法Vue.observable(store)

如此處理之后,不論主應(yīng)用還是微應(yīng)用中零如,修改共享storestate狀態(tài)值躏将,在主應(yīng)用和微應(yīng)用中都能夠?qū)崟r(shí)感知,并對(duì)其做出響應(yīng)的反饋考蕾。

具體實(shí)現(xiàn)(微應(yīng)用本身就有自己store實(shí)例)

這種情況主要考慮的是兩種方案

  1. 主應(yīng)用需要提前得知子應(yīng)用的store內(nèi)容祸憋,將其與主應(yīng)用的store進(jìn)行某種融合,這樣子應(yīng)用在集成環(huán)境中以及在獨(dú)立運(yùn)行時(shí)都能夠正常運(yùn)行肖卧。

    缺點(diǎn):這方方案會(huì)導(dǎo)致主應(yīng)用和子應(yīng)用相互耦合過(guò)強(qiáng)蚯窥,并且主應(yīng)用和子應(yīng)用都要維護(hù)一份子應(yīng)用的store,增加工作量塞帐,過(guò)于笨重拦赠。

  2. 主應(yīng)用依舊只傳遞主應(yīng)用的store,子應(yīng)用的store依舊在使用葵姥,也就是在子應(yīng)用中既可以操作主應(yīng)用的store荷鼠,也可以操作子應(yīng)用的store

    優(yōu)點(diǎn):主應(yīng)用只需關(guān)注需要交互的狀態(tài)即可牌里,不用關(guān)心子應(yīng)用原本的store內(nèi)容颊咬。子應(yīng)用也只需關(guān)注自己的store內(nèi)容即可务甥,降低耦合牡辽,減輕復(fù)雜度喳篇。

父子應(yīng)用store分離的方案實(shí)現(xiàn)

這里基于父應(yīng)用已經(jīng)共享自己的store,并且主應(yīng)用和子應(yīng)用之間已經(jīng)能夠完成對(duì)于主應(yīng)用的state狀態(tài)變化的響應(yīng)态辛◆锢剑考慮如何在子應(yīng)用中使用兩個(gè)storenew Vue()中目前注入的是主應(yīng)用的store奏黑,那子應(yīng)用本身的store如何全局注冊(cè)呢炊邦?仔細(xì)思考后,其實(shí)很簡(jiǎn)單熟史,只需要在入口文件中添加如下一行代碼:

Vue.prototype.microStore = microStore;

如此一來(lái)馁害,在子應(yīng)用的各個(gè)頁(yè)面都能夠通過(guò)this.microStore訪問(wèn)自身的store

computed: {
    microCount: {
        get (){
            return this.microStore.state.microCount;
        }
    }
}

總結(jié)

到此蹂匹,關(guān)于在qiankun的集成中碘菜,主應(yīng)用和子應(yīng)用使用Vuex進(jìn)行通信的基本使用方法介紹結(jié)束了,缺少了子應(yīng)用和子應(yīng)用之間的一個(gè)實(shí)驗(yàn)限寞,大家有興趣可以試試忍啸。

參考

  1. 基于 qiankun 的微前端最佳實(shí)踐(圖文并茂) - 應(yīng)用間通信篇
  2. 目標(biāo)是最完善的微前端解決方案 - qiankun 2.0
  3. qiankun官網(wǎng)API指導(dǎo)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市履植,隨后出現(xiàn)的幾起案子计雌,更是在濱河造成了極大的恐慌,老刑警劉巖玫霎,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凿滤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡庶近,警方通過(guò)查閱死者的電腦和手機(jī)翁脆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拦盹,“玉大人鹃祖,你說(shuō)我怎么就攤上這事∑沼撸” “怎么了恬口?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)沼侣。 經(jīng)常有香客問(wèn)我祖能,道長(zhǎng),這世上最難降的妖魔是什么蛾洛? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任养铸,我火速辦了婚禮雁芙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钞螟。我一直安慰自己兔甘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布鳞滨。 她就那樣靜靜地躺著洞焙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拯啦。 梳的紋絲不亂的頭發(fā)上澡匪,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音褒链,去河邊找鬼唁情。 笑死,一個(gè)胖子當(dāng)著我的面吹牛甫匹,可吹牛的內(nèi)容都是我干的甸鸟。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼赛惩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼哀墓!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起喷兼,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤篮绰,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后季惯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吠各,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年勉抓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贾漏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡藕筋,死狀恐怖纵散,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情隐圾,我是刑警寧澤伍掀,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站暇藏,受9級(jí)特大地震影響蜜笤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盐碱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一把兔、第九天 我趴在偏房一處隱蔽的房頂上張望沪伙。 院中可真熱鬧,春花似錦县好、人聲如沸围橡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)某饰。三九已至儒恋,卻和暖如春善绎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诫尽。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工禀酱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牧嫉。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓剂跟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親酣藻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子曹洽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345