# 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
})