使用qianjkun uniapp 主应用 集成 vue微应用

uniapp 主应用 集成 vue微应用

乾坤官方文档

主应用为uniapp

在主应用安装qiankun框架

bash 复制代码
yarn add qiankun 
#或者
npm install qiankun

因为我们需要动态传递数据,则使用loadMicroApp方法动态加载
pages/work/preview/index页面文件

javascript 复制代码
<template>
	<view class="preview-container">
		<view class="micro-wrap">
			<div id="micro-container"></div>
		</view>
	</view>
</template>

<script>
let microApp = null
import { loadMicroApp } from 'qiankun';
import { getInfo } from '@/api/login'
import actions from '../../../share/actions';
export default {
	components: {},
	data() {
		return {
			loading: false,
			previewId: 1
		}
	},
	async onLoad() {
		await this.init()
	},
	async onUnload() {
		if (microApp) {
			await microApp.unmount()
			microApp = null
		}
	},
	methods: {
		async init() {
			this.loading = true
			actions.setGlobalState({
				previewId: this.previewId
			})
			await this.mountSub()
		},
		async mountSub() {
			const resp = await getInfo();
			// 获取系统信息
			const systemInfo = uni.getSystemInfoSync();
			microApp = loadMicroApp({
				name: 'test',
				entry: 'http://localhost/', //不要写路由 hash
				container: '#micro-container',
				props: {
					userInfo: resp.data,
					systemInfo,
					onGlobalStateChange: actions.onGlobalStateChange,
					setGlobalState: actions.setGlobalState
				},
				sandbox: {
					experimentalStyleIsolation: true //强制性的样式沙箱隔离
				}
			})
			await microApp.mountPromise
			this.loading = false

		}
	}
}
</script>

<style scoped>
.micro-wrap {
	overflow: hidden;
	height: calc(100vh - 44px);
	width: 100%;
}
</style>

share/actions.js文件

javascript 复制代码
import {
	initGlobalState
} from 'qiankun';

// 主应用中注册全局事件
// 设置全局状态
const initialState = {
	currentTab: 0,
	zoomScale: 1,
	mobile: true
};
// 创建全局状态实例并导出
const actions = initGlobalState(initialState);
// 监听全局状态变化(可选)
 actions.onGlobalStateChange((newState, prev) => {
   console.log('主应用监听到全局状态变化:', newState, prev);
 });
export default actions;

微应用

1.在 src 目录新增 public-path.js

javascript 复制代码
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

2.入口文件 main.js 修改,为了避免根 id #app 与其他的 DOM 冲突,需要限制查找范围。

javascript 复制代码
import './public-path'; // 需要放在第一行,不然icon图标会显示不出不来
import store from './store'
import { isMobile } from '@/utils'
let instance = null
/** ================微前端配置================ */
// 如果是在乾坤里面加载,则子应用应该跳过默认的加载逻辑,让主应用来控制当前应用的加载(匹配到子应用的路由标识)
if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}
function render(props = {}) {
  const { container, userInfo, systemInfo } = props
  if (userInfo) {
    store.dispatch('setUserInfo', userInfo)
  }
  if (systemInfo) {
   // 手机样式
    if (isMobile(systemInfo.ua)) {
      document.body.classList.add('ua-mobile');
    } else {
      document.body.classList.add('ua-pc');
    }

  }

  // 监听主应用推过来的全局状态(true = 首次立即触发一次)
  props.onGlobalStateChange && props.onGlobalStateChange((state, prev) => {
    //更新 vuex / 组件状态 / 重新拉数据等
    store.dispatch('qiankun/setQkState', state)
  }, true) // true 表示进来就触发一次
  // 子应用也可以反向通知主应用
  // props.setGlobalState && props.setGlobalState({ childReady: true })
  instance = new Vue({
    el: container ? container.querySelector('#app') : '#app',
    router,
    store,
    render: h => h(App)
  })
}

// qiankun 生命周期
export async function bootstrap() {
  console.log('app bootstraped');
}
export async function mount(props) { render(props) }
export async function unmount() {
  instance.$destroy()
  instance.$el.innerHTML = ''
  instance = null
}

src\store\modules\qiankun.js状态文件

javascript 复制代码
const state = () => ({
    qiankunState: {}   // 主应用下发的全局状态
})
const mutations = {
    SET_QK_STATE(state, payload) {
        state.qiankunState = { ...state.qiankunState, ...payload }
    }
}
const actions = {
    setQkState({ commit }, payload) {
        commit('SET_QK_STATE', payload)
    }
}
export default { namespaced: true, state, mutations, actions }

监听状态变化,在vue文件里面加下下面的代码

javascript 复制代码
 computed: {
    ...mapState({
      // 箭头函数会使代码更简练
      currentTab: state => state.qiankun.qiankunState.currentTab,
      zoomScale: state => state.qiankun.qiankunState.zoomScale
    })
  },
  watch: {
    currentTab(newVal, oldVal) {
      conslole.log(newVal, oldVal)
    },
    zoomScale(newVal, oldVal) {
     conslole.log(newVal, oldVal)
    }
  },

3.打包配置修改(vue.config.js):

javascript 复制代码
const packageName = require('./package.json').name;
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  configureWebpack: {
    output: {
      library: `${packageName}-[name]`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      jsonpFunction: `webpackJsonp_${packageName}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
    },
  },
};

4.新建路由

javascript 复制代码
{
    path: '/pages',
    component: Layout,
    hidden: true,
    redirect: 'noredirect',
    children: [{
      meta: {
        title: '微前端',
      },
      path: 'work/preview/index',
      // component: (resolve) => require(['@/views/hardware/manage/index'], resolve),
      component: (resolve) => require(['@/views/app/preview'], resolve),
      name: 'AppPreview',
      meta: {title: '微前端页面', icon: '', noCache: true}
    }]
  },

注意: 这里的路由地址需要与uniapppages/work/preview/index路径对应上

相关推荐
不一样的少年_2 分钟前
这才是 Vue 驱动的 Chrome 插件工程化正确打开方式
vue.js·chrome·typescript
Juchecar13 分钟前
npm、pnpm、yarn 是什么?该用哪个?怎么用?如何迁移?
前端·node.js
CYRUS_STUDIO15 分钟前
Miniconda 全攻略:优雅管理你的 Python 环境
前端·后端·python
学不动学不明白16 分钟前
ECharts 为visualMap视觉映射添加自适应外边框
前端
怪可爱的地球人20 分钟前
ts的高级类型
前端
支撑前端荣耀21 分钟前
优雅的Git提交:用Husky为你的项目加上提交约束
前端·javascript
支撑前端荣耀22 分钟前
前端CI/CD深度实践:从代码提交到自动化部署的专业化流水线
前端
林太白42 分钟前
npm多组件发布Vue3+TS版本,快来像Antd一样搭建属于你的UI库吧
前端·javascript·node.js
Juchecar1 小时前
如何避免Node.js项目node_modules重复占用空间
前端