微前端micro-app 子应用 调用父应用方法

1 篇文章 0 订阅
1 篇文章 0 订阅

参考:micro-app官方文档

场景描述

父应用存储一套vuex数据,其中包含登录信息token等,登录信息透传给子应用使用。
当子应用中的接口返回“登录失效”时,需要清空父应用vuex中的登录相关信息,并且跳转到登录页面。

原本vuex中有一个名为 LogOut 的action(如下),正常情况直接通过this.$store.dispatch("LogOut") 触发即可。

	...
	// 退出系统
    LogOut({ commit, state }) {
      return new Promise((resolve, reject) => {
        logout(state.token).then(() => {
          commit('SET_TOKEN', '')
          commit('SET_ROLES', [])
          commit('SET_PERMISSIONS', [])
          removeToken()
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },
    ....

但是微前端改造之后,子应用自身没有 vuex 的实例,最后考虑通过 子应用向主应用发送数据 的方式实现功能,原理:

解决办法

  1. 触发条件下,子应用通过 dispatch 向 父应用传递参数:
// 子应用 window.microApp.dispatch 传值
...
window.microApp.dispatch({type: 'callLogOut'})
...
  1. 父应用 通过 绑定监听函数 addDataListener 监听子应用传递的数据
// 父应用监听数据变化
...
microApp.addDataListener(appName, handlerFun);
...

发现问题:父应用只能监听到一次数据变化

上述代码写好之后,项目运行,发现父应用只能监听到一次数据变化,之后再次触发该特定场景,父组件始终无法监听到数据变化,即使子应用明明触发的 dispatch

经仔细查阅 父子应用传值文档,发现:

dispatch只接受对象作为参数,它发送的数据都会被缓存下来。 micro-app会遍历新旧值中的每个key判断值是否有变化,如果所有数据都相同则不会发送(注意:只会遍历第一层key),如果数据有变化则将新旧值进行合并后发送。

例如:

// 第一次发送数据,记入缓存值 {name: 'jack'},然后发送 
window.microApp.dispatch({name: 'jack'})
// 第二次发送数据,将新旧值合并为 {name: 'jack', age: 20},记入缓存值,然后发送 
window.microApp.dispatch({age: 20})
// 第三次发送数据,新旧值合并为 {name: 'jack', age: 20},与缓存值相同,不再发送
window.microApp.dispatch({age: 20})

dispatch是异步执行的,多个dispatch会在下一帧合并为一次执行

window.microApp.dispatch({name: 'jack'})
window.microApp.dispatch({age: 20})

// 上面的数据会在下一帧合并为对象{name: 'jack', age: 20}一次性发送给主应用

解决方法

那么,有没有什么办法,不缓存参数,做到每次场景触发,子应用给父应用传值,父应用都能及时监听到并触发对应操作呢

有,那就是 forceDispatch:强制发送

forceDispatch方法拥有和dispatch一样的参数和行为,唯一不同的是forceDispatch会强制发送数据,无论数据是否变化。

示例:

// 强制发送数据,无论缓存中是否已经存在 name: 'jack' 的值
window.microApp.forceDispatch({name: 'jack'}, () => {
  console.log('数据已经发送完成')
})

最终代码

// 子应用
...
	// 重新登录
  	window.microApp.forceDispatch({type: 'callLogOut'})
...


// 父应用
...
  mounted() {
    // 父应用中监听子应用触发的自定义事件
    microApp.addDataListener('app-deploy', this.subListener)
  },
  beforeDestroy() {
    // 移除监听
    microApp.removeDataListener('app-deploy', this.subListener)
  },
  methods: {
    subListener(data) {
      // 登录过期,跳转首页并退出登录
      if (data?.type === 'callLogOut') {
        this.$store.dispatch('LogOut').then(() => {
          location.href = '/index'
        })
      }
    },
    ...
  }
...

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端卡卡西呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值