# 1. 桌面端微前端接入

# qiankun + vue2 项目

# (1) vue.config.js

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

module.exports = {
    publicPath: '/kpi/', // 🌟 项目资源的基础路径
    devServer: {
        headers: {
            'Access-Control-Allow-Origin': '*' // 🌟 开发环境跨域配置
        }
    },
    ...... // 省略与接入不相关的代码
    configureWebpack: {
        output: {
            library: `${name}`, // 🌟 子应用的名称取自package.json的name
            libraryTarget: 'umd', // 把子应用打包成 umd 库格式
            jsonpFunction: `webpackJsonp_${name}`
        }
    }
}

# (2) src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Layout from '../views/Layout.vue'

Vue.use(Router)
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
    return originalPush.call(this, location).catch((err) => err)
};

// 🌟 桌面端和Web端兼容
const ENV_QIANKUN = window.__POWERED_BY_QIANKUN__ && !window.location.pathname.includes('/portal')

// 🌟🌟🌟 桌面端接入的子应用路由:桌面端根路由 + 子应用根路由 + 具体的页面路由
const routes = [
    {
        path: '/',
        redirect: ENV_QIANKUN ? '/home/kpi/app1' : '/app1'
    },
    {
        path: ENV_QIANKUN ? '/home/kpi' : '/',
        name: 'layout',
        component: Layout,
        redirect: ENV_QIANKUN ? '/home/kpi/app1' : '/app1',
        children: [{
            path: 'app1',
            name: 'app1',
            component: () => import('../views/app1.vue')
        },
        {
            path: 'app2',
            name: 'app2',
            component: () => import('../views/app2.vue')
        }]
    }
]

const createRouter = () =>
    new Router({
        // base: 'kpi', // 🌟 不要设置base
        mode: 'hash', // 🌟🌟🌟 子应用必须使用hash模式, 不支持history模式
        scrollBehavior: () => ({ y: 0 }),
        routes: routes
    })

export default createRouter()

# (3) main.js

import './public-path' // 🌟 引入环境变量
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false;

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

    instance = new Vue({
        router,
        store,
        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) {
    console.log('[vue] props from main framework', props);
    render(props)
}
export async function unmount() {
    instance.$destroy()
    instance.$el.innerHTML = ''
    instance = null
}

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

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