1.2.1 • Published 8 months ago

web-message-center v1.2.1

Weekly downloads
-
License
MIT
Repository
-
Last release
8 months ago

web-message-center

web 的消息中心插件

基于发布-订阅模式思想,利用 window.postMessage 封装的浏览器父子标签之间、父子页面、iframe 之间通信插件,消息名称及消息内容均可自定义

基础使用

在一个页面中引入
import WebMessageCenter from "web-message-center"
const wmc = new WebMessageCenter();

wmc.emit("message", {
  from: "parent",
  contents: "我是父页面",
});


在另外一个 iframe、页面中
import WebMessageCenter from "web-message-center"
const wmc = new WebMessageCenter();

wmc.on("message", function (data) {
  console.log('form:'data.from + "contents" + data.contents);
});

api

constructor

const wmc = new WebMessageCenter(options)

options 参数是可选的,支持如下:

名称类型含义
originString页面源,设置后只能在同一源(同一 url)下才能通信 *
channelString频道,处于同一频道下的 WebMessageCenter 才能相互通信
verifyDomainFunction校验发消息的来源,function (url) { return url.indexOf("https://my-domain") === 0; }, 只有返回 true 的时候才能接收到消息
targetFramesArray给那些 iframe 发消息(Window (t window.open的返回值) 或 HTMLFrameElement (iframe 元素)),也可以通过 wmc.addTargetFrame(myIframe);动态添加

target static

target(options),options 同上

// 只接收来自https://example.com的消息
wmc.target({ origin: 'https://example.com' }).on('message', () => {})

emit

emit('event', data?, reply?): boolean

参数类型描述
eventString事件名称
dataAny传递的内容
callbackFunction为订阅者提供的回调函数

on

on('event', fn): boolean

参数类型描述
eventString事件名称
fn(data?, reply?)Function事件处理函数,均来自于emit函数

once

触发回调后,立即注销监听,回调只触发一次

once('event', fn): boolean

参数类型描述
eventString事件名称
fn(data?, reply?)Function事件处理函数,均来自于emit函数

addTargetFrame

动态添加 targetFrames

include

动态添加 childWindow,即动态添加可广播 window

const newWin = window.open('https://example.com')
wmc.include(newWin)

off

off('event', fn): boolean

取消订阅

teardown

销毁实例

global

emitononceoff有对应的globalAPI,可以监听指定频道的通信、触发全局消息

API全局API
emitemitGlobal
ononGlobal
onceonceGlobal
offoffGlobal

yzw-helper

针对一张网业务场景,在web-message-center基础上提供扩展API

引入

import WebMessageCenter, { provide, inject, openTab } from 'web-message-center/dist/yzw-helper.mini.js'
const yzwHelper = new WebMessageCenter()

api

provide

构建WebMessageCenter对象,用于创建和指定子应用的私有通信频道,必须指明一个targetFrames

需要子应用配合使用inject API初始化

provide(options, props)

名称类型含义
optionsObject初始化参数,结构同构造函数参数
propsObject子应用加载初始化参数

options同构造函数,props为主应用传递的初始化数据

// 主应用
const options = {
  channel: channel, // 可由主应用指定,不传时由组件内生成uuid
  targetFrames: [iframeElement]
}
const props = {}; // 初始化参数
const wmc = WebMessageCenter.provide(options, props);

// 子应用,获取通信对象和初始化数据后渲染页面
inject((), (wmc, props) => {
  render(wmc, props);
});

inject

使用init方法可获取和主应用的私有通信频道,配合主应用使用provide初始化时,可获取初始化数据

inject(options, initCallback)

名称类型含义
optionsObject初始化参数,结构同构造函数参数
initCallbackFunction初始化回调函数,参数:wmc通信对象,props组件初始化参数

使用实例参考provide

openTab

应用需要打开浏览器新页签时,调用openTab方法,支持传入初始化数据

openTab(url, props)

名称类型含义
urlString新页签地址
propsObject打开新页签传递初始化数据

子应用使用通信组件完整示例

qiankun

以qiankun官方Vue微应用示例为基础,罗列引入通信组件改动点

初始化:

// main.js

/**
 * 1. 引入组件
 * 2. 独立运行时,使用inject初始化(ie11使用iframe集成业务组件)
 * 3. qiankun的mount方法,使用WebMessageCenter初始化
 * 4. 改造render方法,将通信示例挂载到Vue实例上
 */
import './public-path'
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import routes from './router'
import store from './store'

// 1. 引入组件
import { inject, default as WebMessageCenter } from 'web-message-center/dist/yzw-helper.mini.js'

Vue.config.productionTip = false

let router = null
let instance = null

// 4. 改造render方法,将初始化返回的方法或属性定义为全局属性
function render(wmc, props = {}) {
  const { container } = props
  // 方法或属性定义到Vue原型或通过其他方式,保证组件可以调用
  Vue.prototype.$wmc = wmc

  instance = new Vue({
    router,
    store,
    render: (h) => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')
}

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  // 2. 独立运行时,使用inject初始化(ie11使用iframe集成业务组件)
  // 独立运行时,inject 相当于 new WebMessageCenter()
  // 如果url里有channelKey,inject 相当于 new WebMessageCenter({channel: channelKeyValue })
  inject({}, (wmc, props) => {
    render(wmc, props)
  })
}

export async function bootstrap() {
  console.log('[vue] vue app bootstraped')
}
export async function mount(props) {
  console.log('[vue] props from main framework', props)
  // 3. qiankun的mount方法,使用WebMessageCenter初始化
  const channel = props.name
  inject({ channel }, (wmc, props) => {
    render(wmc, props)
  })
}
export async function unmount() {
  instance.$destroy()
  instance.$el.innerHTML = ''
  instance = null
  router = null
}

使用通信API:

// App.vue

<script>
  export default {
    mounted() {
      // 组件渲染完毕后,通知父应用关闭遮罩
      this.$wmc.emit({
        info: {
          _cmd: 'mounted'
        }
      })
      // 监听换肤操作
      this.$wmc.onGlobal('Msg_babgpt_customize-change', this.themeCallback)
    },
    methods: {
      themeCallback(message) {
        const theme = message.info?.windowOptions?.theme
        // 执行换肤
      }
    }
  }
</script>

非qiankun组件

非qiankun组件以iframe的方式嵌入,或window.open打开新页签,以vue举例。

// main.js

/**
 * 1. 引入组件
 * 2. 使用inject初始化
 * 3. 改造render方法,将初始化返回的方法或属性定义为全局属性
 */
import Vue from 'vue'
import Router from 'vue-router'
import App from './App.vue'

import router from '@/router/index.js'

import { pinia, PiniaVuePlugin } from '@/plugins/pinia.js'

const app = new Vue({
  router,
  pinia,
  render: (h) => h(App)
})

// 1. 引入组件
import { inject } from 'web-message-center/dist/yzw-helper.mini.js'

// 2. 使用inject初始化
const loadPage = inject({}, (wmc, props) => {
  // 3. 改造render方法,将初始化返回的方法或属性定义为全局属性
  // 方法或属性定义到Vue原型或通过其他方式,保证组件可以调用
  Vue.prototype.$wmc = wmc
  // props用于初始化操作
  app.$mount('#app')
})

通信API的使用参考qiankun示例中的API使用。

1.2.1

8 months ago

1.2.0

8 months ago

1.1.1

10 months ago

1.1.0

10 months ago

1.0.2

11 months ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

2 years ago

0.0.1

2 years ago