A项目(react)使用iframe 嵌套B(react) 项目时候需要传递一个对象;
private gettaskDetailIframeSrc = () => { const { currentGroup } = this.props; let origin = location.origin; let path = '/app/oa'; let search = `?${agent.setCurrentOrg(currentGroup.orgType, currentGroup.orgId)}`; if ($config.isLocal) { // 如果是本地 端口号对应的是index的mappingPort配置的端口 origin = `${location.protocol}//${location.hostname}:3001`; path = ""; } return `${origin}${path}?home=home`; // 查看 }
<iframe id="iframeDetail" style={{ width: "100%", height: "100%", border: "none" }} src={this.gettaskDetailIframeSrc()} ></iframe>
在事件触发是传递参数
private call(item) {
const iframeObj = document.getElementById('iframeDetail') as HTMLIFrameElement;
iframeObj.addEventListener('load', () => {
iframeObj.contentWindow.postMessage(JSON.stringify(item), '*')
})
}
为什么要监听load ,因为我们要等ifreame 渲染完才能继续传递数据
那么B页面如何接收呢,这问题最开始很简单的放在了最外层的windows上
let propsBody: $api.TaskDetails = {};
window.onload = () => {
window.addEventListener('message', (e) => {
if (typeof e.data === 'string') {
propsBody = JSON.parse(e.data);
}
})
}
。。。。
public componentDidMount() {
this.setState({
approvalProcessLoading: false,
propsList: propsBody
})
}
这么二的写法当时真的不知道怎么想的,但是该说不说确实好用,本地一点问题没有,热而部署到服务器没被气死。
在本地测试时候记载顺序是先触发了window.onload,在触发componentDidMount ,而部署后完全是反过来的
后来发现自己一直纠结的点不对,我一直在考虑window.onload 和componentDidMount的加载顺序问题,我忽略了本质问题,那就是数据传输时候是在B页面完成后在传递的,那是不是说在componentDidMount周期内部我可以接受参数,遂部署测试,验证了我的猜测。然后为了兼容本地方便调试和部署环境兼容做了以下处理
if ($config.isLocal) {
this.setState({
approvalProcessLoading: false,
propsList: propsBody
})
this.renderJurisdiction(propsBody);
} else {
window.addEventListener('message', (params) => {
if (params) {
this.setState({
approvalProcessLoading: false,
propsList: JSON.parse(params.data)
})
this.renderJurisdiction(JSON.parse(params.data));
}
}, false);
}