美文网首页
微前端乾坤框架的实际应用

微前端乾坤框架的实际应用

作者: 张晓畅 | 来源:发表于2023-08-24 10:23 被阅读0次

    上来就干货!

    主应用(基座)

    h5_config.js 配置(引入到index.html)

    window.SITE_CONFIG = {};
    window.SITE_CONFIG['appName'] = '微前端‘;
    window.SITE_CONFIG['storeState'] = {} // vuex本地储存初始化状态(用于不刷新页面的情况下,也能重置初始化项目中所有状态)
    
    //微应用
    window.MicroPre = 'http://127.0.0.1'
    window.microApps = [
        // 子应用1
        {
            name: 'subApp1',
            entry: MicroPre+':8001/',
            container: '#micro-app',
            activeRule: '/subapp1',
        },
        // 子应用2
        {
            name: 'subApp2',
            entry: MicroPre+':8002/',
            container: '#micro-app',
            activeRule: '/subapp2',
        },
    ]
    

    main.js

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import store from './store'
    import http from '@/utils/request'
    import cloneDeep from 'lodash/cloneDeep'
    
    //==========================微前端=====start
    import { registerMicroApps, start, addGlobalUncaughtErrorHandler } from 'qiankun';
    // 子应用
    window.microApps = window.microApps.map(item=>{
      item.props = {
        microData:{
          entry:item.entry,
          parentStore:store,
          parentRouter:router,
          ProjectData: '额外参数'
        }
      }
      return item;
    })
    registerMicroApps(window.microApps,{
      beforeLoad: (app) => {
        store.commit("qiankunFinish",true);
        console.log('beforeLoad, 子应用注册:', app.name)
      },
      beforeMount: (app) => {
        console.log('beforeMount,子应用挂载前:', app.name)
      },
      afterMount: (app) => {
        store.commit("qiankunFinish",false);
        console.log('afterMount,子应用挂载:', app.name)
      },
      beforeUnmount:(app)=>{
        store.commit("qiankunFinish",true);
        console.log('beforeUnmount,子应用卸载前:', app.name)
      },
      afterUnmount: (app) =>{
        store.commit("qiankunFinish",false);
        console.log("afterUnmount,卸载后", app.name)
      },
    
    });
    
    addGlobalUncaughtErrorHandler(e => {
      console.log('qk error:', e)
      const {message: msg} =e
      if(msg&&msg.includes('died in status LOADING_SOURCE_CODE')){
        console.log('微应用加载失败, 请检查应用是否可用')
      }
    })
    
    start({prefetch:true});
    //==========================微前端=====end
    
    Vue.config.productionTip = false
    
    // 挂载全局
    Vue.prototype.$http = http
    
    // 保存整站vuex本地储存初始状态
    window.SITE_CONFIG['storeState'] = cloneDeep(store.state)
    // 主应用(基座)
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#micro-service')
    

    子应用

    创建public-path

    if (window.__POWERED_BY_QIANKUN__) {
        __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
    }
    

    创建qiankun.js

    import './public-path'; // 微前端路径
    import Vue from 'vue';
    import Router from 'vue-router'
    import Cookies from 'js-cookie'
    import http from '@/utils/request'
    
    Vue.config.productionTip = false
    
    Vue.use(Router);
    
    // 挂载全局
    Vue.prototype.$http = http
    
    /**
     * 
     * @param {*} App 
     * @param {*} store 
     * @param {*} setting 微服务配置
     * @param {*} projectFiles 文件夹下的路由
     * @param {*} otherRoutes :各自项目自定义的路由
     * @returns 
     */
    export default function qiankun(App, store, setting, projectFiles,otherRoutes=[]){
        let instance = ''
        let router = ''
        const isQiankun = !!window.__POWERED_BY_QIANKUN__;//当前是微
        function render(props={}) {
            const { container } = props;
            const defaultRoutes =  [...otherRoutes];
            router = new Router({
                base: isQiankun ? `/${setting.QIANKUN_APP_NAME}` : setting[process.env.NODE_ENV],
                mode: 'history',
                scrollBehavior: () => ({ y: 0 }),
                routes:defaultRoutes
            })
              
            Vue.config.performance = process.env.NODE_ENV === 'development';
            instance = new Vue({
                router,
                store,
                render: h => h(App)
            }).$mount(container ? container.querySelector(`#${setting.QIANKUN_APP_NAME}`) : `#${setting.QIANKUN_APP_NAME}`);
        }
        
        // 微前端钩子
        async function bootstrap() {
            console.log('[vue] 微应用初始化时调用一次');
        }
        async function mount(props) {
            const microData = props.microData;
            window.entry = microData.entry || "";
            window.ProjectData = microData.ProjectData;
            window.parentStore = microData.parentStore;
            window.parentRouter = microData.parentRouter;
            console.log(window.parentStore)
            console.log('[vue] 应用每次进入都会触发渲染', props);
            let token = window.parentStore.state.token
            token && Cookies.set('token', window.parentStore.state.token)
            render(props);
        }
        async function unmount() {
            console.log('[vue] 应用每次切出/卸载都会触发');
            instance.$destroy();
            instance.$el.innerHTML = '';
            instance = null;
            router = null;
            window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] = false;
            console.log('销毁成功')
        }
        return {render, bootstrap, mount, unmount}
    }
    

    setting.js 配置

    module.exports = {
        QIANKUN_APP_NAME: "subApp1",// 子应用的名称
        production: '/child/subApp1/', // 生产环境打包路径(根据实际部署环境配置)
        devlopment: './', // 本地运行路径
    }
    

    main.js

    import Vue from 'vue';
    import App from './App'
    import * as directiverData from '@/utils/directive';
    import store from './store'
    import qiankun from '@/qiankun'
    
    import cloneDeep from 'lodash/cloneDeep'
    
    for(let name in directiverData){
        Vue.directive(name,{inserted:directiverData[name]});
    }
    
    const setting = require('./setting.js')
    
    window.SITE_CONFIG['storeState'] = cloneDeep(store.state)
    
    Vue.prototype.$setting = setting
    const projectFiles = require.context('./views', true, /\.vue$/).keys()
    const init = qiankun(App, store, setting, projectFiles)
    
    // 独立运行时
    if (!window.__POWERED_BY_QIANKUN__) {
        console.log('独立')
        init.render();
    }
    
    // 抛出乾坤钩子
    export const {bootstrap,mount,unmount} = init;
    

    相关文章

      网友评论

          本文标题:微前端乾坤框架的实际应用

          本文链接:https://www.haomeiwen.com/subject/mwymmdtx.html