# 1. web端老项目微前端接入

# qiankun + vue2 项目,以物料管理hwork-web-marketing-uo (opens new window)项目为例

# (1) vue.config.js

const { name } = require('./package')

module.exports = {
    runtimeCompiler: true,
    publicPath: process.env.NODE_ENV === 'development' ? '/' : '/marketing/', // 🌟 项目资源的基础路径,marketing是物料管理项目,改成自己项目对应的名称。
    devServer: {
        headers: {
            'Access-Control-Allow-Origin': '*' // 🌟 开发环境跨域配置
        }
    },
    ...... // 省略与接入不相关的代码
    configureWebpack: {
        output: {
            library: `${name}`, // 🌟 子应用的名称取自package.json的name
            libraryTarget: 'umd', // 把子应用打包成 umd 库格式
            jsonpFunction: `webpackJsonp_${name}`
        }
    },
    chainWebpack(config) {
        config.plugins.delete('preload')  // 🌟 如果有preload,会挂载不上
        config.plugins.delete('prefetch') // 🌟 如果有prefetch,会挂载不上

        config.module // 🌟 解决非base64图片,加载失败问题
            .rule('images')
            .use('url-loader')
            .loader('url-loader')
            .tap(options => Object.assign(options, { limit: Infinity }))
            .end()
    }
}

# (2) src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

// import Hwork from 'hwork-web-component'; 🌟 注释掉 老包hwork-web-component
// const { Login, Layout } = Hwork;
const Layout = ({ template: '<router-view />' }) // 🌟 新的 Layout 组件
import { rememberFrom } from '@/utils/auth'
rememberFrom()

export const constantRoutes = [
  ...... // 项目具体的路由配置,省略
  // { path: '*', redirect: '/404', hidden: true } // 🌟 注释掉 默认跳转到404页面
];

const router = (mainName = '') => // 🌟 mainName参数来自主应用
  new Router({
    base: window.__POWERED_BY_QIANKUN__ ? `${mainName}/marketing/` : '/marketing/', // 🌟 marketing是物料管理项目,改成自己项目对应的名称。
    mode: 'history', // require service support
    scrollBehavior: () => ({ y: 0 }),
    routes: constantRoutes
  });

export default router

# (3) main.js

import './public-path' // 🌟 引入环境变量
import actions from './actions' // 🌟 引入actions文件
import Vuex from 'vuex'

// import Hwork from 'hwork-web-component' 🌟 注释掉 老包hwork-web-component
// const { initPermission } = Hwork
// initPermission(router, store)

...... // 省略与接入不相关的代码

// new Vue({
//   el: '#app',
//   router,
//   store,
//   render: h => h(App)
// })

let instance = null
function render (props = {}) {
    const { container } = props // 🌟 获取主应用传递过来的数据
    let newStore

    if (props && props.actions) { // 🌟 获取主应用传递过来的数据
        actions.setActions(props.actions)
    }
    if (props && props.store) { // 🌟 获取主应用传递过来的数据
        newStore = storeConcat(store, props.store.default)
    }

    instance = new Vue({
        provide: { mainAppRouter: props.mainAppRouter }, // 🌟 获取主应用传递过来的路由,直接挂载到实例
        router: router(props.mainName), // 🌟 将主应用的路由值
        store: newStore,
        render: (h) => h(App)
    }).$mount(container ? container.querySelector('#app') : '#app')
}

// 非乾坤环境下,独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
    render()
}

export async function bootstrap () {
    console.log('[vue] vue app bootstraped')
}
export async function mount (props) {
    // 🌟 防止子应用渲染完后,获取不到主应用传递过来的数据
    (await props.onGlobalStateChange(async(obj) => {
        if (obj.userInfo.userCode && obj.limitsList && obj.limitsList.length > 0) {
            render(props)
        }
    }, true))
}
export async function unmount () {
    instance.$destroy()
    instance.$el.innerHTML = ''
    instance = null
}

function storeConcat(target, source) {
    const newStore = target
    const map = {
        state: {},
        getters: {},
        _actions: {},
        _mutations: {}
    }
    for (const key in map) {
      [source].forEach(s => {
          for (const k in s[key]) {
              newStore[key][k] = s[key][k]
          }
      })
    }

    return newStore
}

# (4) src 目录新增 public-path.js

/* eslint-disable */
if (window.__POWERED_BY_QIANKUN__) {
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}

# (5) src 目录新增 actions.js

function emptyAction () {
  console.warn('Current execute action is empty!')
}

class Actions {
    actions = {
      onGlobalStateChange: emptyAction,
      setGlobalState: emptyAction
    }

    // 默认值为空Action
    // 设置actions
    setActions (actions) {
      this.actions = actions
    }

    // 映射
    onGlobalStateChange (...args) {
      return this.actions.onGlobalStateChange(...args)
    }

    // 映射
    setGlobalState (...args) {
      return this.actions.setGlobalState(...args)
    }
}
const actions = new Actions()
export default actions

# (6) 修改 src/App.vue

import actions from './actions'
<script>
export default {
    ...... // 省略与接入不相关的代码
    mounted () {
      actions.onGlobalStateChange(state => { // onGlobalStateChange的第二个参数设置为true,则会立即触发一次观察者函数
        console.log('子应用接收到的数据----', state) // 🌟 获取主应用传递过来的用户信息、token等
      }, true)
    }
}
</script>

# (7) 修改 public/index.html

<!-- <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.14&key=69ce8f833120cb4e31669f380ac48d40&plugin=AMap.Autocomplete"></script> -->
<!-- 🌟 高德地图升级到2.0 -->
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=69ce8f833120cb4e31669f380ac48d40&plugin=AMap.Autocomplete"></script>

# (8) 修改 src/store/index.js

注释掉 hwork-web-component 相关的逻辑

// import Hwork from 'hwork-web-component'
// const { n_app, n_sidemenu, n_user, n_permission, npmGetters } = Hwork

const setGetters = () => {
  return {
    ...getters,
    // ...npmGetters
  }
}

// 导入npm包中的模块
// modules.n_app = n_app
// modules.n_sidemenu = n_sidemenu
// modules.n_user = n_user
// modules.n_permission = n_permission

const store = new Vuex.Store({
  // modules,
  // getters: gets
})