博客 / 詳情

返回

uniapp作為乾坤子應用配置

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主應用配置完成
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.