background
页面之间需要通信但无直接逻辑关系。
页面 | A | B | C |
---|---|---|---|
说明 | 公共页面(组件)/表单页 | A的子组件/审批操作页 | 列表查询页 |
C页面
有“查询”和“处理”两种按钮,都跳转至A页面,使数据回填,只有编辑状态的差异,待办列表上有数字提醒,当代办数量发生变化(即列表中的数据被处理掉)需要立即改变相应的数字提醒;
B页面
是实际的审批页面,在这里处理数据后,会改变C页面的数据待办数量;
A页面
是C页面的跳转页面,承载数据详细信息,有相应的操作按钮打开字组件B页面。
C跳转至A通过window.open打开。
export function jumpWebPopup(url, queryParams, that) {
let routerUrl = that.$router.resolve({
path: url,
query: queryParams
});
let height = window.screen.height - 90;
let width = window.screen.width - 10;
let childWin = window.open(routerUrl.href, "_blank", 'top=0, left=0, height=' + height + ', width=' + width);
window.onmessage = function(e){
alert('我收到回应了!')
if((typeof e.data) === 'string' && e.data === 'refreshTable'){
storeVuex.dispatch('getToDoNum');//获取待办事项数量
bus.$emit('reFresh', null);
}
}
}
B与C之间并没有直接的逻辑关系但需要B触发C中的方法,这里用到了onmessage/postMassage通信以及中央事件总线。
中央事件总线
就是页面通信,bus很形象
onmessage/postMessage通信
postMessage和onmessage是HTML5的方法,用来解决跨页面通信,或者通过iframe嵌套的不同页面的通信的。postMessage为发送方,onmessage为接收方。
案例里出现了不同域的通信导致数据无法传输。
代码实现
common中引入bus
eventBus.js
import Vue from 'vue';
export default new Vue();
C页面引入bus
import bus from "common/eventBus";
......
created(){
this.loadTable();
bus.$on('reFresh', target => {
this.form.pageNumber = 1;
this.loadTable();
});
}
mounted() {
this.shopbus.$on('refreshtables', () => {
this.form.pageNumber = 1;
this.loadTable();
});
},
B页面最终操作时首先出发父组件A的方法shepiSucsses
this.$emit('shepiSucsses', this.gwid);
A页面给出回应
this.shopbus.$emit('refreshtables');
window.opener.postMessage('refreshTable', '*');
//此时会触发C页面中window.ommessage下alert以及 bus.$emit('reFresh', null);实现C的列表刷新