Vue2 qiankun主應(yīng)用改造

1、安裝 qiankun

npm i qiankun

2、創(chuàng)建入口文件register.js

import { registerMicroApps, start, initGlobalState } from 'qiankun'
import store from '@/store'
import { env } from '@/utils/config'

// 注冊微應(yīng)用通信示例
const initialState = {}
export const actions = initGlobalState(initialState)

// qiankun全局狀態(tài)監(jiān)聽
// actions.onGlobalStateChange((state, prev) => {
//   // state: 變更后的狀態(tài); prev 變更前的狀態(tài)
// })
actions.setGlobalState({ fullScreen: false })

export let microApps = [
  {
    name: 'person',
    entry: {
      development: 'http://localhost:8080/',
      sit: '',
      production: '',
      private: ''
    }[env],
    container: '#micro-app',
    activeRule: '/micro-app/person',
    meta: { // 做權(quán)限、菜單顯示等邏輯處理
      productCode: 'A',
      name: '人員管理',
      icon: require('@/assets/image/1.png'),
      key: 'A',
    }
  },
  {
    name: 'permission',
    entry: {
      development: 'http://localhost:8081/',
      sit: '',
      production: '',
      private: ''
    }[env],
    container: '#micro-app',
    activeRule: '/micro-app/permission',
    meta: {
      productCode: 'B',
      name: '權(quán)限管理',
      icon: require('@/assets/image/2.png'),
      key: 'B',
    }
  },
]

// qiankun配置
registerMicroApps(microApps, {
  beforeMount: (app) => {
    // 設(shè)置產(chǎn)品編碼(解決回退產(chǎn)品編碼不一致問題)
    store.commit('user/SET_PRODUCT_CODE', app.meta.productCode)
  }
})

start({
  prefetch: false,
  sandbox: {
    experimentalStyleIsolation: true // 主子應(yīng)用樣式隔離
  },
  excludeAssetFilter: assetUrl => { // 指定部分特殊的動態(tài)加載的微應(yīng)用資源(css/js) 不被 qiankun 劫持處理
    // 自定義白名單鏈接
    const whiteList = []
    /**
     * 白名單協(xié)議:子應(yīng)用下如需要放行動態(tài)加載的css/js資源,可以在鏈接上帶上參數(shù) _custom-exclude_=MAIN
     */
    const whiteWords = ['_custom-exclude_=MAIN'] // 白名單關(guān)鍵詞:協(xié)議制定 _custom-exclude_=MAIN。
    if (whiteList.includes(assetUrl)) {
      return true
    }
    return whiteWords.some(w => {
      return assetUrl.includes(w)
    })
  }
})

3、引入
main.js

// qiankun注冊子應(yīng)用
import './utils/register'

4、容器

layout
<template>
  <div class="app-wrapper">
    <div v-if="showHeader" class="app-header">
      <Header />
    </div>
    <div id="micro-app" class="app-container">
      <app-main class="app-main" />
    </div>
  </div>
</template>

<script>
import Header from './components/Header'
import AppMain from './components/AppMain.vue'
import { actions } from '@/utils/register'
export default {
  name: 'Layout',
  components: {
    Header,
    AppMain
  },
  data() {
    return {
      showHeader: true
    }
  },
  created() {
    if (this.$route.query.fullScreen === 'true') {
      this.showHeader = false
    }
  },
  mounted() {
    this.listenGlobalState()
  },
  methods: {
    listenGlobalState() {
      // qiankun全局狀態(tài)
      actions.onGlobalStateChange((state) => {
        if (state.fullScreen === true) {
          this.showHeader = false
        } else {
          this.showHeader = true
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
  .app-wrapper {
    height: 100%;
    display: flex;
    flex-direction: column;
    .app-header {
      height: 50px;
      line-height: 50px;
    }
    .app-container {
      width: 100%;
      flex: 1;
      height: 0;
      .sidebar {
        width: 210px;
        background-color: rgb(48, 65, 86);
        overflow: scroll;
      }
      .app-main {
        flex: 1;
        min-height: calc(100% - 50px);
        width: 100%;
      }
    }
    .app-container>div {
      width: 100%;
    }
  }

</style>

Header
<template>
  <el-menu
    :default-active="activeIndex"
    class="top-menu"
    mode="horizontal"
    @select="handleSelect"
  >
    <el-menu-item v-for="(item) in productList" :key="item.productCode" :index="item.productCode">{{ item.productName }}</el-menu-item>
  </el-menu>
</template>

<script>
import { mapGetters } from 'vuex'
import mcroAppLink from '@/utils/mcroAppLink'
export default {
  name: 'TopMenu',
  data() {
    return {
      activeIndex: ''
    }
  },
  computed: {
    ...mapGetters([
      'productList',
      'productCode'
    ])
  },
  watch: {
    productCode: {
      handler(val) {
        this.activeIndex = val
      },
      immediate: true
    }
  },
  methods: {
    // 切換產(chǎn)品
    handleSelect(val) {
      let activeRule = mcroAppLink(val)
      this.$router.push(activeRule)
    }
  }
}
</script>
AppMain
<template>
  <section>
    <transition name="fade-transform" mode="out-in">
      <div id="app-vue">
        <router-view :key="key" />
      </div>
    </transition>
  </section>
</template>

<script>
export default {
  name: 'AppMain',
  computed: {
    key() {
      return this.$route.path
    }
  }
}
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容