您好,登錄后才能下訂單哦!
本篇內(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í)!
免責(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)容。