首先说下postMessage,它是 html5 引入的 API,postMessage() 方法允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档,多窗口,跨域消息传递。多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案。
发送数据
otherWindow.postMessage(message, targetOrigin, [transfer]);
接收数据
window.addEventListener("message", receiveMessage, false) ;
function receiveMessage(event) {
var origin= event.origin;
console.log(event);
}
然后我们封装一个跨域传值函数
/**
*
* @param {String} type 通信标识
* @param {String} content 通信内容
*/
export function postMessage(type, content) {
window.parent.postMessage({
type,
content
}, '*')
}
我们要做的是父系统控制子系统a页面点击按钮执行路由跳转到b页面的子页面(只展示子组件)
这里是子系统a页面:
在a页面按钮触发事件方法中进行发送消息,告诉父系统我要跳转到b页面的子页面
// 引入通信函数
import { postMessage } from 'utils'
// 点击按钮跳转方法
btnToPush(...) {
// 通信标识指定为'router',通信内容为路由url并携带showChildPage字段表示展示子组件
postMessage('router', 'xxx/xxx?params=' + JSON.stringify({showChildPage: true}))
}
在子系统b页面进行接收a页面的信息
// 在methods里定义一个方法用来接收相关信息
getRouterData() {
const query = this.$route.query
if(query.params) {
const params = JSON.parse(decodeURIComponent(query.params))
this.viewChildPage = params.showChildPage
}
},
在父系统layout.vue文件中监听子系统发送的消息
//父系统layout.vue
// 生成实例后监听子系统发送的消息
created () {
this.$nextTick(() => {
window.addEventListener('message', this.porps)
})
},
// 销毁实例前移除监听
beforeDestroy () {
this.$nextTick(() => {
window.removeEventListener('message', this.porps)
})
},
methods: {
props(event) {
// 拿到子系统传来的数据
const data = event.data
// 验证约定通信标识
if(data.type === 'router') {
this.$router.push(`./${data.content}`)
}
}
...
}
这样就实现了父系统控制子系统内部路由跳转及组件切换展示的功能!!!