qiankun自定义数据通信方案

  1. 监听初始推送一次
  2. 合并多次变更
  3. 自动回收副作用

dataBus.js

/* 
dataBus 单例
state
dispatch
forceDispatch
onListener @return offListner
offListner
initData
 */
import { reactive, watch } from 'vue'
import { tryOnBeforeUnmount } from '@vueuse/core'

let dataBus

function useTasks() {
  const tasks = new Set()

  function _runTasks() {
    tasks.forEach((task) => task())
  }

  function runTask(task) {
    tasks.add(task)
    Promise.resolve().then(() => {
      _runTasks()
      tasks.clear()
    })
  }
  return {
    runTask
  }
}

function createFactory(initialData = {}) {
  const state = reactive(initialData)
  const listeners = new Set()
  const { runTask } = useTasks()

  watch(
    () => state,
    () => {
      runTask(_exe)
    },
    { deep: true }
  )

  function _exe(newVal = state) {
    listeners.forEach((listener) => listener(newVal))
  }

  function dispatch(newState) {
    Object.assign(state, newState)
  }

  function forceDispatch(newState) {
    dispatch(newState)
    runTask(_exe)
  }

  function onListener(callback, initialPush) {
    listeners.add(callback)
    if (initialPush) runTask(_exe)
    const clean = offListner.bind(this, callback)
    tryOnBeforeUnmount(clean)
    return clean
  }

  function offListner(callback) {
    listeners.delete(callback)
  }

  dataBus = {
    state,
    dispatch,
    forceDispatch,
    onListener,
    offListner
  }
}

createFactory()

export function initData(initialData = {}) {
  const data = dataBus.state
  Object.keys(data).forEach(key => {
    delete data[key];
  });
  Object.assign(data, initialData)
}

export default dataBus

MicroApp.vue

import dataBus from '@/utils/dataBus'

onMounted(() => {
  if (window.registedMicroApps) return
  window.registedMicroApps = true
  registerMicroApps([
    {
      name: 'report',
      entry: 'http://localhost:8080',
      container: '.micro-app-container',
      activeRule: '/child/report',
      props: {
        dataBus,
      }
    }
  ])
  start({
    sandbox: {
      experimentalStyleIsolation: true
    }
  })
})

主应用使用例子1

import { initData } from '@/utils/dataBus'

initData({
  collapse: false
})

主应用使用例子2

<template>
	<div class="main-content">
		state.collapse: {{ state.collapse }}
		<el-radio-group v-model="state.collapse" style="margin-bottom: 20px" @change="handleSwichChange">
			<el-radio-button :value="false">expand</el-radio-button>
			<el-radio-button :value="true">collapse</el-radio-button>
		</el-radio-group>
		<RouterView />
	</div>
</template>

<script setup>
	import dataBus from '@/utils/dataBus'
	const { state } = dataBus
</script>

微应用main.js

async function render(props = {}) {
  const { container, dataBus } = props;

  window.$dataBus = dataBus;
}

微应用使用例子1

created() {
    if (window.$dataBus) {
      const { onListener } = window.$dataBus;
      onListener((data) => {
        console.log("data变化:", data);
        this.collapse = data.collapse;
      }, true);
    }
}

微应用使用例子2

const { state, forceDispatch, onListener } = window.$dataBus || {};

function toggle() {
  if (!window.$dataBus) return;
  forceDispatch({ collapse: !state.collapse });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值