Toggle navigation
集客麦麦@谢坤
首页
随笔
首页
>>
创作中心
>>
微前端开发(二), ...
微前端开发(二), 使用过程的若干问题解决方案
Not Found
[TOC] ## 子应用 hash 方式连接 ### 1. 基座模式配置, 基座以 hash 方式访问 路由配置: ```js import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router' import Home from '../views/Home.vue' const routes: Array
= [ { path: '/vue', name: 'Vue', component: () => import('../views/child1-vue.vue') } ] const router = createRouter({ history: createWebHashHistory(), routes }) export default router ``` main.ts ```js import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' import { registerMicroApps, start } from 'qiankun' // 子应用为 hash 模式配置, 步骤1 const getActiveRule = (hash:string) => (location:any) => location.hash.startsWith(hash) const app = [ { name: 'vueApp', entry: 'http://localhost:10002', container: '#vue-app', activeRule: getActiveRule('#/vue') // 这里也可以直接写 activeRule: '#/vue',但是如果主应用是 history 模式或者主应用部署在非根目录,这样写不会生效。 } ] registerMicroApps(app) start({ sandbox: true }) createApp(App).use(store).use(router).mount('#app') ``` ### 2. 子应用路由设置为 hash `vue-router` 的 `hash` 模式下不支持设置路由的 `base`,需要额外新建一个空的路由页面,将其他所有路由都作为它的 `children`: ```js import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' import hashLayout from '../views/hashModLayout' Vue.use(VueRouter) const routes = [ { path: '/vue', name: 'vueHashLayout', component: hashLayout, children: [ { path: '/vue', name: 'Home', component: Home }, { path: 'about', name: 'About', component: () => import('../views/About.vue') }, { path: 'prop-of-main', name: 'propOfMain', component: () => import('@/views/Test.vue') } ] } ] const router = new VueRouter({ mode: 'hash', // vue2 默认 hash, 也可不设置 routes }) export default router ``` ## 基座应用与子应用的通信传递 ### 基座应用配置 ```js import { initGlobalState, MicroAppStateActions } from 'qiankun'; // 初始化 state const actions: MicroAppStateActions = initGlobalState(state); actions.onGlobalStateChange((state, prev) => { // state: 变更后的状态; prev 变更前的状态 console.log(state, prev); }); actions.setGlobalState(state); actions.offGlobalStateChange(); ``` ### 子应用配置 ```js // 从生命周期 mount 中获取通信方法,使用方式和 master 一致 export function mount(props) { props.onGlobalStateChange((state, prev) => { // state: 变更后的状态; prev 变更前的状态 console.log(state, prev); }); props.setGlobalState(state); } ``` ## 基座应用点击子应用子路由加载失败 原因, 基座路由需要与子应用路由有一对一映射关系 ### 基座路由配置 ```js // ... { path: '/vue', name: 'Vue', component: Child1App }, { path: '/vue/about', name: 'VueAbout', component: Child1App }, { path: '/vue/prop-of-main', name: 'VuePropOfMain', component: Child1App } // ... ``` ### 子路由(hash 方式)配置 ```js const routes = [ { path: '/vue', name: 'vueHashLayout', component: hashLayout, children: [ { path: '/vue', name: 'Home', component: Home }, { path: 'about', name: 'About', component: () => import('../views/About.vue') }, { path: 'prop-of-main', name: 'propOfMain', component: () => import('@/views/Test.vue') } ] } ] ``` ## 基座应用能否直接引用子应用的组件 不能, 微应用是基于路由引入的所以一般是将子应用需要引用的组件封装成路由页面进行交互 ## 基座应用不同路径配置相应子应用 基座应用配置, main.ts ```js import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' import { registerMicroApps, start } from 'qiankun' // 子应用为 hash 模式配置, 步骤1 const getActiveRule = (hash:string) => (location:any) => location.hash.startsWith(hash) const app = [ { name: 'vueApp', entry: 'http://127.0.0.1:10002', container: '#vue-app', activeRule: getActiveRule('#/vue') }, { name: 'vue-app1', entry: 'http://localhost:10003', container: '#vue-child2', activeRule: getActiveRule('#/app1') } ] registerMicroApps(app) start({ sandbox: true }) createApp(App).use(store).use(router).mount('#app') ``` 子应用1 1. main.js ```js const { name } = require('./package') module.exports = { devServer: { port: 10003, headers: { 'Access-Control-Allow-Origin': '*' } }, configureWebpack: { output: { library: 'vue-app1', libraryTarget: 'umd', // 把微应用打包成 umd 库格式 jsonpFunction: `webpackJsonp_${name}` } } } ``` 2. vue.config.js ```js const { name } = require('./package') module.exports = { devServer: { port: 10003, headers: { 'Access-Control-Allow-Origin': '*' } }, configureWebpack: { output: { library: 'vue-app1', libraryTarget: 'umd', // 把微应用打包成 umd 库格式 jsonpFunction: `webpackJsonp_${name}` } } } ``` 3. App.vue ```vue
Home
|
About
``` 4. router/index.js ```js import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' import hashLayout from '../views/hashModLayout' Vue.use(VueRouter) const routes = [ { path: '/app1', name: 'vueHashLayout', component: hashLayout, children: [ { path: '/app1', name: 'Home', component: Home }, { path: 'about', name: 'About', component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ] } ] const router = new VueRouter({ mode: 'hash', routes }) export default router ``` ## 基座应用单页面加载单个子应用多个页面 官方说明: `页面上不能同时显示多个依赖于路由的微应用,因为浏览器只有一个 url,如果有多个依赖路由的微应用同时被激活,那么必定会导致其中一个 404。` ## 基座应用单页面加载多个子应用 loadMicroApp ### 基座应用配置 #### 组件 例如: Child1App12.vue ```vue
应用1,2联合
``` #### 路由 ```js //... { path: '/combone12', name: 'VueApp1Combone12', component: () => import('@/view/Child1App12') } //... ``` ### 子应用1 #### 路由 ```js { path: '/combone12', name: 'combone12', component: Home } ``` ### 子应用2 #### 路由 ```js { path: '/combone12', name: 'combone12', component: () => import('@/views/Test.vue') } ```