uniapp作为乾坤子应用配置


  • 项目背景:

    新人入职接手老项目,该项目是利用uniapp框架开发,主要是兼容web和微信小程序。近日收到新的需求,要将web端嵌入甲方的主应用。

  • 技术栈

    1. 主应用框架umi ;主应用打包方式hash
    2. 子应用框架uniapp,vue2的写法,老项目是hbuilder创建的应用,子应用打包方式hash

      注:umimax自带qiankun在配置中开启即可

  • 注意点:

    1. uniapp作为子应用在manifest.json配置文件中设置路由的base不生效
    2. 子应用模板里的id="app"修改此处的id为其他不生效
  • 主应用注册子应用配置

    1. 子应用名称和base都设置为uniapp-app
    import { defineConfig } from '@umijs/max';
    
    export default defineConfig({
      qiankun: {
        master: {
          apps: [
            {
              name: 'uniapp-app',//子应用名称
              entry: '//localhost:20092',//子应用入口
            },
          ]
        },
      },
      antd: {},
      access: {},
      model: {},
      initialState: {},
      request: {},
      layout: {
      },
      history: {
        type:"hash"
      },
      routes: [
        {
          name: '首页',
          path: '/uniapp-app/*',//设置路由的base,子应用的base要为uniapp-app
          microApp: 'uniapp-app',//子应用名称
        }
      ],
    });
    
    
  • 子应用配置

    ​ 注:子应用根目录下的package.jsonname字段设置为uniapp-app

    1. 此处的base设置不生效,所以不用填

      image.png

    2. 项目根路径下public-path.js内容如下

      // #ifdef H5 || WEB
      if (window.__POWERED_BY_QIANKUN__) {
          __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
      }
      // #endif

​ 3. 在main.js文件第一行引入该文件,如下图

image.png

​ 4.在main.js配置如下代码

// #ifdef H5 || WEB
let instance
if (!window.__POWERED_BY_QIANKUN__) {
    let app = new Vue({
        store,
        ...App
    })
    app.$mount('#app');
}
export async function mount(props) {
    console.log('mount', props)
   //若主应用没有调用子应用的 unmount钩子,每次挂在的时候销毁实例
    if (instance) { 
        instance.$el.innerHTML = '';
        instance.$destroy();
        instance = null;
    }
    instance = new Vue({
        store,
        ...App
    })
    instance.$mount(props.container ? props.container.querySelector('#app') : '#app');
    return Promise.resolve()
}
export async function bootstrap(props) {
    console.log('bootstrap', props)
    return Promise.resolve()
}
//销毁子应用实例
export async function unmount(props) {
    console.log('unmount', props)
    instance.$el.innerHTML = '';
    instance.$destroy();
    instance = null;
    return Promise.resolve()
}
// #endif

5.在子应用根路径下创建vue.config.js文件;内容如下

const { name } = require('./package');
module.exports = {
    devServer: {
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    },
    configureWebpack: {
        output: {
            library: `${name}-[name]`,
            libraryTarget: 'umd', // 把微应用打包成 umd 库格式
            jsonpFunction: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
        },
    },
};

6.由于uniapp的路由设置base不生效,打包成web的时候,pages.json里面的路径就是打包后的访问路径,如:pages.json的路径配置是pages/home/indexhash模式下真是的访问路径为www.xxx.com/#/pages.home/index,由于我们创建的子应用对应的baseuniapp-app所以我们需要在根路径下创建uniapp-app文件夹,将所有的页面放到该文件下,如下图

image.png

修改pages.json的配置如果是有分包的情况下,也需要加上该路径,如图

image.png

  • 出现的问题

    1.主应用跳转子应用,子应用页面滑动不了;在根路径的uni.scss文件中加入如下代码

    // 解决子应用不能滚动的问题
    // #ifdef H5 || WEB
    uni-page-body>uni-view {
        height: 100vh;
        overflow: auto !important;
        width: 100vw;
    }
    
    // #endif

    2.主应用跳转到子应用首页,子应用点击其他页面后在其他页面点击进入子应用的首页,页面显示空白;跳转首页的时候利用history.pushState或者history.replaceState方式跳转,需要根据运行环境判断

    3.若主应用没有调用子应用的卸载方法;每次在挂在的时候销毁实例,见上面子应用配置第四步

  • 到此uniapp作为子应用嵌入到qiankun主应用配置完成

GeGeZZ
6 声望0 粉丝

« 上一篇
webpack5学习