您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“微前端qiankun改造實(shí)例分析”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“微前端qiankun改造實(shí)例分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。
首先我先用vue2-admin-cli——我自己做的腳手架工具,創(chuàng)建兩個(gè)vue-admin項(xiàng)目來演示,一個(gè)作為qiankun基座,另外一個(gè)就是我要引用的子應(yīng)用。
全局安裝腳手架 npm install -g vue2-admin-cli # or yarn global add vue2-admin-cli 創(chuàng)建項(xiàng)目 vue2-admin-cli init <project_name> 安裝依賴 yarn 啟動項(xiàng)目 yarn serve
運(yùn)行起來就是這樣的
現(xiàn)在我們開始分別改造基座qiankun-base和子應(yīng)用qiankun-vue,我想達(dá)到的效果是主應(yīng)用qiankun-base只保留header sider footer的一個(gè)基本layout的布局,content部分全部加載子應(yīng)用
yarn add qiankun # 或者 npm i qiankun -S 修改package.json啟動命令修改啟動端口 "serve": "vue-cli-service serve --port 80 --open" src/router/index.ts修改路由模式為history const createRouter = () => new VueRouter({ mode: "history", routes: routes as any, }); 修改vue.config.js 我這里之前用的路由模式是hash 上線配置了publicPath 導(dǎo)致改為history以后靜態(tài)資源加載路徑有問題所以修改 module.exports = { // publicPath: "./", devServer: { disableHostCheck: true, // 關(guān)閉host檢查 }, };
在入口文件src/main.ts下注冊微應(yīng)用并啟動:
import { registerMicroApps, start } from "qiankun"; registerMicroApps([ { name: "qiankunVue", entry: "//localhost:8080", 子應(yīng)用的啟動端口修改為8080,基座使用80,不要相同 container: "#qiankunVue", 加載子應(yīng)用的容器 activeRule: "/qiankunVue", 路由匹配規(guī)則 }, ]); // 啟動 qiankun start();
在你要放置子應(yīng)用的位置增加一個(gè)容器用于加載子應(yīng)用
src/components/layout/index.vue
<template> <el-container direction="vertical" > <Header /> <el-container > <el-aside width="250px"> <Menu /> </el-aside> <el-main> <el-breadcrumb separator-class="el-icon-arrow-right" v-if="showBreadcrumb" > <template v-for="(route, index) in matchedRoutes"> <el-breadcrumb-item v-if=" (route.meta && route.meta.breadcrumbTo === false) || index === matchedRoutes.length - 1 " :key="route.path" > {{ route.meta.title }} </el-breadcrumb-item> <el-breadcrumb-item v-else :key="route.path" :to="{ path: route.path }" > {{ route.meta.title }} </el-breadcrumb-item> </template> </el-breadcrumb> <!-- 本身的路由加載 --> <router-view /> <!-- 子應(yīng)用加載容器 --> <div id="qiankunVue" /> </el-main> </el-container> </el-container> </template>
將主應(yīng)用之前的路由配置進(jìn)行修改,不渲染自己的內(nèi)容了,因?yàn)橐某扇ゼ虞d子應(yīng)用的內(nèi)容才是我們想要的,我的左側(cè)菜單欄sider也是用路由配置這份文件生成的,所以我只需要注釋這些路由要渲染的components就行,讓他只充當(dāng)一個(gè)生成sider菜單欄的作用,但是注意要保留容器所在的layout,因?yàn)槲业淖討?yīng)用加載容器在這里面,加載子應(yīng)用之前你必須保證容器被加載了
src/router/config.ts
const routes: Array<IBaseRouter> = [ { path: "/", redirect: "/home", hidden: true, }, { path: "/login", name: "login", hidden: true, component: () => import("../views/Login.vue"), }, //保證子應(yīng)用加載時(shí)容器頁面必須加載 { path: "/qiankunVue/*", name: "qiankunVue", hidden: true, component: Layout, }, { path: "/qiankunVue/home", name: "home", component: Layout, redirect: "/qiankunVue/home/index", meta: { title: "首頁", icon: "el-icon-s-home", }, children: [ { path: "index", name: "index", hidden: true, // component: () => import("../views/Home.vue"), meta: { title: "首頁", breadcrumb: false, }, }, { path: "bar/:width/:height", name: "bar", props: true, hidden: true, // component: () => import("@/components/echarts/Bar.vue"), meta: { title: "柱狀圖", activeMenu: "/home/index", }, }, { path: "pie/:width/:height", name: "pie", props: true, hidden: true, // component: () => import("@/components/echarts/Pie.vue"), meta: { title: "餅圖", activeMenu: "/home/index", }, }, { path: "line/:width/:height", name: "line", props: true, hidden: true, // component: () => import("@/components/echarts/Line.vue"), meta: { title: "折線圖", activeMenu: "/home/index", }, }, ], }, ..... { path: "*", redirect: "/error/404", hidden: true, }, ]; export default routes;
改完之后刷新看一看,這樣基座項(xiàng)目就改造好了,保留了基本頁面的框架,中間的內(nèi)容到時(shí)候都由子應(yīng)用來填充就行了
修改package.json啟動命令修改啟動端口
"serve": "vue-cli-service serve --port 8080 --open"
入口文件 src/main.ts 修改
let vm: any = null; function render(props: any = {}) { const { container } = props; vm = new Vue({ router, store, render: (h) => h(App), }).$mount(container ? container.querySelector("#app") : "#app"); } // 在被qiankun引用時(shí) 修改運(yùn)行時(shí)的 `publicPath` if ((window as any).__POWERED_BY_QIANKUN__) { __webpack_public_path__ = (window as any).__INJECTED_PUBLIC_PATH_BY_QIANKUN__; } // 獨(dú)立運(yùn)行時(shí) if (!(window as any).__POWERED_BY_QIANKUN__) { render(); } 導(dǎo)出三個(gè)生命周期函數(shù) export async function bootstrap() { console.log("[vue] vue app bootstraped"); } export async function mount(props: any) { console.log("[vue] props from main framework", props); render(props); } export async function unmount() { vm.$destroy(); vm.$el.innerHTML = ""; vm = null; } export default vm;
src/router/index.ts修改路由模式并增加base(和主應(yīng)用設(shè)置的activeRule一致)
const createRouter = () => new VueRouter({ mode: "history", base: "/qiankunVue", routes: routes as any });
打包配置修改(`vue.config.js`)
module.exports = { devServer: { disableHostCheck: true, // 關(guān)閉host檢查 headers: { "Access-Control-Allow-Origin": "*", // 防止加載時(shí)跨域 }, }, configureWebpack: { output: { library: "qiankunVue", libraryTarget: "umd", // 把微應(yīng)用打包成 umd 庫格式 }, }, };
基座和子應(yīng)用都修改完以后刷新看看,控制臺報(bào)錯(cuò)了
立馬查看官方文檔,發(fā)現(xiàn)是因?yàn)槲业淖討?yīng)用加載容器在基座的某個(gè)路由頁面即我的layout里面,文檔里指出必須保證微應(yīng)用加載時(shí)主應(yīng)用這個(gè)路由頁面也加載了,就很喜歡這種文檔????????,于是立馬改一改
注釋之前qiankun-base注冊子應(yīng)用時(shí)的啟動qiankun命令,改到路由頁面layout里面啟動
src/main.ts
// 啟動 qiankun //start(); src/components/layout/index.vue import { start } from "qiankun"; mounted() { if (!(window as any).qiankunStarted) { (window as any).qiankunStarted = true; start(); } }
重新刷新看看,成功了????????,多少有點(diǎn)舒服了
接下來要做的就是把子應(yīng)用再改造一下,在qiankun中就只需要展示子應(yīng)用content的內(nèi)容,單獨(dú)運(yùn)行的時(shí)候?yàn)榱朔奖阏{(diào)試我們就保留layout布局。看了這么久的官方文檔,我當(dāng)然知道用它就可以做出判斷__POWERED_BY_QIANKUN__,思路很清晰,沖他????????
qiankun-vue
src/components/layout/index.vue
<template> <el-container direction="vertical" v-if="isQiankun"> <el-main> <el-breadcrumb separator-class="el-icon-arrow-right" v-if="showBreadcrumb" > <template v-for="(route, index) in matchedRoutes"> <el-breadcrumb-item v-if=" (route.meta && route.meta.breadcrumbTo === false) || index === matchedRoutes.length - 1 " :key="route.path" > {{ route.meta.title }} <!-- {{ route.path }} --> </el-breadcrumb-item> <el-breadcrumb-item v-else :key="route.path" :to="{ path: route.path }" > {{ route.meta.title }} <!-- {{ route.path }} --> </el-breadcrumb-item> </template> </el-breadcrumb> <router-view /> </el-main> </el-container> <el-container direction="vertical" v-else> <Header /> <el-container > <el-aside width="250px"> <Menu /> </el-aside> <el-main> <el-breadcrumb separator-class="el-icon-arrow-right" v-if="showBreadcrumb" > <template v-for="(route, index) in matchedRoutes"> <el-breadcrumb-item v-if=" (route.meta && route.meta.breadcrumbTo === false) || index === matchedRoutes.length - 1 " :key="route.path" > {{ route.meta.title }} <!-- {{ route.path }} --> </el-breadcrumb-item> <el-breadcrumb-item v-else :key="route.path" :to="{ path: route.path }" > {{ route.meta.title }} <!-- {{ route.path }} --> </el-breadcrumb-item> </template> </el-breadcrumb> <router-view /> </el-main> </el-container> </el-container> </template> <script lang="ts"> import { Vue, Component } from "vue-property-decorator"; import Header from "./Header.vue"; import Menu from "./Menu.vue"; // import { IBaseRouter } from "@/router/config"; @Component({ name: "Layout", components: { Header, Menu }, }) export default class Layout extends Vue { private get showBreadcrumb() { return this.$route?.meta?.breadcrumbAll !== false; } private get matchedRoutes() { return this.$route.matched?.filter( (v) => v.meta?.title && v?.meta?.breadcrumb !== false ); } private get isQiankun() { return (window as any).__POWERED_BY_QIANKUN__; } } </script> <style lang="less" scoped></style>
看看效果 基座正常展示子應(yīng)用
子應(yīng)用單獨(dú)運(yùn)行也正常展示,并且絲毫不影響開發(fā)體驗(yàn)
讀到這里,這篇“微前端qiankun改造實(shí)例分析”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。