本篇內容主要講解“微前端qiankun項目實踐案例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“微前端qiankun項目實踐案例分析”吧!
那什么是 qiankun 呢
qiankun 是一個基于 single-spa 的微前端實現庫,旨在幫助大家能更簡單、無痛的構建一個生產可用微前端架構系統。
什么是微前端
微前端架構具備以下幾個核心價值:
技術棧無關
主框架不限制接入應用的技術棧,微應用具備完全自主權
獨立開發、獨立部署
微應用倉庫獨立,前后端可獨立開發,部署完成后主框架自動完成同步更新
增量升級
在面對各種復雜場景時,我們通常很難對一個已經存在的系統做全量的技術棧升級或重構,而微前端是一種非常好的實施漸進式重構的手段和策略
獨立運行時
每個微應用之間狀態隔離,運行時狀態不共享
摘自 qiankun官方文檔
主應用配置
此次項目 主應用與 子應用均為 vue ,
下載 qiankun
npm install qiankun
在主應用中注冊微應用
// 導入乾坤函數
import { registerMicroApps, setDefaultMountApp, start } from "qiankun";
封裝 render 方法
此方法在main.js 中要初始調用一次, 主要用來掛載主應用 , 之后子應用分別依次調用 ,所以故作判斷. 傳入的參數分別為 子應用 的 HTML 和 加載狀態 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); } }
微應用注冊
下文中的apps 可以為獲取后數據 , 注冊微應用 本文案例比較簡單,方便大家理解 ,
在注冊自應用的參數 ** container 與 render** 踩坑比較多,下邊會著重講解.
function genActiveRule(routerPrefix) { return location => location.pathname.startsWith(routerPrefix); } //傳遞給子應用的數據 let msg = {  data:'修煉愛情的辛酸,學會放好以前的渴望' } let apps = [ { name: 'linjunjie', entry: '//localhost:215', // 改成自己子應用的端口號 container:'#subView', //節點 id // 沙盒模式 // render:render, // 普通模式 activeRule: genActiveRule('/star'), props:msg } ] //注冊的子應用 參數為數組 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} })
當微應用信息注冊完之后,一旦瀏覽器的 url 發生變化,便會自動觸發 qiankun 的匹配邏輯,所有 activeRule 規則匹配上的微應用就會被插入到指定的 container 中,同時依次調用微應用暴露出的生命周期鉤子。
主應用為子應用準備的 展示元素
<template> <div id="app"> <div id="nav"> <!--//主應用 為子應用的跳轉dom--> <div @click="onChangePage('/star/linjunjie')" >林俊杰</div> <div @click="onChangePage('/star/zhangyixin')" >張藝興</div> </div> <!--//用來展子應用的 內容區--> <div id="subView" class="sub-content-wrap" v-html="content"></div> </div> </template> <script> import { mapState } from 'vuex'; export default{ data(){ return { } }, computed:{ //獲取子應用HTML 數據 ...mapState('microApp', ['content']), ...mapState('microApp', ['mircoAppLoading']), }, methods:{ //定義跳轉方法 onChangePage(url){ console.log(url) this.routerGo(url, '我喜愛的男明星') }, routerGo(href = '/', title = null, stateObj = {}) { window.history.pushState(stateObj, title, href); }, } } </script>
子應用配置
關于子應用的配置相對較簡單 , 不需要額外下載qiankun 主要將生命鉤子 導出即可
導出響應的生命鉤子
導出 bootstrap、mount、unmount 三個生命周期鉤子,以供主應用在適當的時機調用。注意,實例化路由時,判斷當運行在qiankun環境時,路由要添加前綴,前綴與主應用注冊子應用函數genActiveRule("/subdemo")內的參數一致
'star' 值需要與主應用的值對應 genActiveRule("/star") 中的值需要商定好 主應用與微應用都要使用
如果 new VueRouter 不在main.js 中 配置 ,請將此配置移動到 main.js 方便管理
import routes from './router' //將路由信息導出方便使用 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 包含主應用傳遞的參數 也包括為子應用 創建的節點信息 console.log(props) render(props); } export async function unmount() { instance.$destroy(); instance = null; router = null; }
配置微應用的打包工具
除了代碼中暴露出相應的生命周期鉤子之外,為了讓主應用能正確識別微應用暴露出來的一些信息,微應用的打包工具需要在vue.config.js 中 增加如下配置:
const packageName = require('./package.json').name; module.exports = { output: { library: `${packageName}-[name]`, libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${packageName}`, }, };
子應用判斷
子應用中新建 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}`, }, }, };
踩坑記錄
當前頁面為子應用時, 刷新頁面404
以下方式均為主應用配置
方式一 刪除 mode 配置項
mode: 'history', // 將此配置代碼刪除
方式二 配置404 頁面
如果沒有注釋掉mode: 'history' 此參數 將404 頁面重新導向 home首頁
{ path: '*', name: 'indexNotFound', component: resolve => require(['@/components/home'], resolve), children: HomeChild, },
子應用 樣式隔離 開始沙箱模式 遇到的問題
主應用配置sandbox :{strictStyleIsolation: true}渲染模式由 render 模式 改為 containercontainer:'#subView', 此時 子應用的 掛載 dom 為 <div id="subView"> </div> 謹記主 container :#+id
子應用配置 上文有提到 主要代碼 截取
instance = new Vue({ router, store, render: h => h(App), }).$mount(container ? container.querySelector('#app') : '#app'); //重點
遇到的問題: 開啟沙箱模式,如果是 采用 render 模式會報錯 ,故選擇container 模式
到此,相信大家對“微前端qiankun項目實踐案例分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。