溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

微前端qiankun項目實踐案例分析

發(fā)布時間:2021-11-15 11:27:17 來源:億速云 閱讀:309 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“微前端qiankun項目實踐案例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“微前端qiankun項目實踐案例分析”吧!

那什么是 qiankun 呢

qiankun 是一個基于 single-spa 的微前端實現(xiàn)庫,旨在幫助大家能更簡單、無痛的構(gòu)建一個生產(chǎn)可用微前端架構(gòu)系統(tǒng)。

什么是微前端

微前端架構(gòu)具備以下幾個核心價值:

  •  技術(shù)棧無關(guān)

        主框架不限制接入應(yīng)用的技術(shù)棧,微應(yīng)用具備完全自主權(quán)

  •  獨立開發(fā)、獨立部署

         微應(yīng)用倉庫獨立,前后端可獨立開發(fā),部署完成后主框架自動完成同步更新

  •  增量升級

        在面對各種復(fù)雜場景時,我們通常很難對一個已經(jīng)存在的系統(tǒng)做全量的技術(shù)棧升級或重構(gòu),而微前端是一種非常好的實施漸進式重構(gòu)的手段和策略

  •  獨立運行時

        每個微應(yīng)用之間狀態(tài)隔離,運行時狀態(tài)不共享

摘自 qiankun官方文檔

主應(yīng)用配置

此次項目 主應(yīng)用與 子應(yīng)用均為 vue ,

下載 qiankun

npm install qiankun

在主應(yīng)用中注冊微應(yīng)用

// 導(dǎo)入乾坤函數(shù)

import {   registerMicroApps,    setDefaultMountApp,    start  } from "qiankun";

封裝 render 方法

此方法在main.js 中要初始調(diào)用一次, 主要用來掛載主應(yīng)用 , 之后子應(yīng)用分別依次調(diào)用 ,所以故作判斷. 傳入的參數(shù)分別為 子應(yīng)用 的 HTML 和 加載狀態(tài) content 字段 我們用 vuex 存儲 起來,方便使用

let app = null;  function render({ appContent, loading }) {    if (!app) {      app = new Vue({        router,        store,        render: h => h(App),      }).$mount('#app');    } else {      store.commit('microApp/changeCenter', appContent);      store.commit('microApp/changeLoading', loading);    }  }

微應(yīng)用注冊

下文中的apps 可以為獲取后數(shù)據(jù) , 注冊微應(yīng)用 本文案例比較簡單,方便大家理解 ,

在注冊自應(yīng)用的參數(shù) ** container 與 render** 踩坑比較多,下邊會著重講解.

function genActiveRule(routerPrefix) {    return location => location.pathname.startsWith(routerPrefix);  }  //傳遞給子應(yīng)用的數(shù)據(jù)  let msg = {  ![](https://user-gold-cdn.xitu.io/2020/4/27/171bbc5de042ec98?w=1811&h=959&f=gif&s=4951066)    data:'修煉愛情的辛酸,學(xué)會放好以前的渴望'  } let apps = [    {      name: 'linjunjie',       entry: '//localhost:215',  // 改成自己子應(yīng)用的端口號      container:'#subView', //節(jié)點 id   //  沙盒模式       // render:render,  // 普通模式         activeRule: genActiveRule('/star'),      props:msg    }  ]     //注冊的子應(yīng)用 參數(shù)為數(shù)組  registerMicroApps(apps,{    beforeLoad: [      app => {        console.log(app)        console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);      },    ],    beforeMount: [      app => {        console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);      },    ],    afterUnmount: [      app => {        console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);      },    ],  });  setDefaultMountApp('/star/linjunjie')  //開啟沙盒模式  start({      sandbox :{strictStyleIsolation: true}  })

當(dāng)微應(yīng)用信息注冊完之后,一旦瀏覽器的 url 發(fā)生變化,便會自動觸發(fā) qiankun 的匹配邏輯,所有 activeRule 規(guī)則匹配上的微應(yīng)用就會被插入到指定的 container 中,同時依次調(diào)用微應(yīng)用暴露出的生命周期鉤子。

主應(yīng)用為子應(yīng)用準(zhǔn)備的 展示元素

<template>    <div id="app">      <div id="nav">        <!--//主應(yīng)用 為子應(yīng)用的跳轉(zhuǎn)dom-->        <div @click="onChangePage('/star/linjunjie')" >林俊杰</div>        <div @click="onChangePage('/star/zhangyixin')" >張藝興</div>       </div>  <!--//用來展子應(yīng)用的 內(nèi)容區(qū)-->       <div id="subView" class="sub-content-wrap" v-html="content"></div>    </div>  </template>  <script>    import { mapState } from 'vuex';    export default{      data(){        return {           }      },      computed:{      //獲取子應(yīng)用HTML 數(shù)據(jù)         ...mapState('microApp', ['content']),         ...mapState('microApp', ['mircoAppLoading']),      },      methods:{          //定義跳轉(zhuǎn)方法        onChangePage(url){          console.log(url)               this.routerGo(url, '我喜愛的男明星')        },        routerGo(href = '/', title = null, stateObj = {}) {          window.history.pushState(stateObj, title, href);         },      }   }  </script>

子應(yīng)用配置

關(guān)于子應(yīng)用的配置相對較簡單 , 不需要額外下載qiankun 主要將生命鉤子 導(dǎo)出即可

導(dǎo)出響應(yīng)的生命鉤子

導(dǎo)出 bootstrap、mount、unmount 三個生命周期鉤子,以供主應(yīng)用在適當(dāng)?shù)臅r機調(diào)用。注意,實例化路由時,判斷當(dāng)運行在qiankun環(huán)境時,路由要添加前綴,前綴與主應(yīng)用注冊子應(yīng)用函數(shù)genActiveRule("/subdemo")內(nèi)的參數(shù)一致

'star' 值需要與主應(yīng)用的值對應(yīng) genActiveRule("/star") 中的值需要商定好 主應(yīng)用與微應(yīng)用都要使用

如果 new VueRouter 不在main.js  中 配置 ,請將此配置移動到 main.js  方便管理

import routes from './router' //將路由信息導(dǎo)出方便使用   let router = null;  let instance = null;  function render(props = {}) {    const { container } = props;    router = new VueRouter({      base: window.__POWERED_BY_QIANKUN__ ? '/star' : '/',        mode: 'history',      routes,    });    instance = new Vue({      router,      store,      render: h => h(App),    }).$mount(container ? container.querySelector('#app') : '#app');  }  if (!window.__POWERED_BY_QIANKUN__) {    render();  }  export async function bootstrap() {    console.log('[vue] vue app bootstraped');  }  export async function mount(props) {   //props 包含主應(yīng)用傳遞的參數(shù)  也包括為子應(yīng)用 創(chuàng)建的節(jié)點信息    console.log(props)    render(props);  }  export async function unmount() {    instance.$destroy();    instance = null;    router = null;  }

配置微應(yīng)用的打包工具

除了代碼中暴露出相應(yīng)的生命周期鉤子之外,為了讓主應(yīng)用能正確識別微應(yīng)用暴露出來的一些信息,微應(yīng)用的打包工具需要在vue.config.js 中 增加如下配置:

const packageName = require('./package.json').name;  module.exports = {    output: {      library: `${packageName}-[name]`,      libraryTarget: 'umd',      jsonpFunction: `webpackJsonp_${packageName}`,    },  };

子應(yīng)用判斷

子應(yīng)用中新建 publicPath.js  在main.js 引入

if (window.__POWERED_BY_QIANKUN__) {   //處理資源   __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;   }

處理 資源加載問題

配置 vue.config.js

module.exports = {    publicPath:`//localhost:${port}`,  }

vue.config.js 完整配置

const path = require('path');  const packageName = require('./package').name;  function resolve(dir) {    return path.join(__dirname, dir);  }  const port = 7101; // dev port  module.exports = {    publicPath:`//localhost:${port}`,    outputDir: 'dist',    assetsDir: 'static',    filenameHashing: true,    devServer: {      // host: '0.0.0.0',      hot: true,      historyApiFallback: true,//添加 重點      port,      overlay: {        warnings: false,       errors: true,      },      headers: {        'Access-Control-Allow-Origin': '*',      },   },    configureWebpack: {      resolve: {        alias: {          '@': resolve('src'),        },      },      output: {        library: `${packageName}-[name]`,        libraryTarget: 'umd',        jsonpFunction: `webpackJsonp_${packageName}`,      },    },  };

踩坑記錄

當(dāng)前頁面為子應(yīng)用時, 刷新頁面404

以下方式均為主應(yīng)用配置

  •  方式一 刪除 mode 配置項   

mode: 'history', //   將此配置代碼刪除
  •  方式二 配置404  頁面

如果沒有注釋掉mode: 'history'  此參數(shù) 將404 頁面重新導(dǎo)向  home首頁

{      path: '*',      name: 'indexNotFound',      component: resolve => require(['@/components/home'], resolve),      children: HomeChild,  },

子應(yīng)用 樣式隔離 開始沙箱模式 遇到的問題

  •  主應(yīng)用配置sandbox :{strictStyleIsolation: true}渲染模式由 render 模式 改為 containercontainer:'#subView', 此時 子應(yīng)用的 掛載 dom  為 <div id="subView"> </div>   謹記主 container :#+id

  •  子應(yīng)用配置 上文有提到  主要代碼 截取 

instance = new Vue({     router,     store,     render: h => h(App),   }).$mount(container ? container.querySelector('#app') : '#app'); //重點

遇到的問題: 開啟沙箱模式,如果是 采用 render 模式會報錯 ,故選擇container 模式

到此,相信大家對“微前端qiankun項目實踐案例分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI