一、​​vForm引入使用​

根据文档完成4.1、4.2内容;

二、封装vFormEdit

<template>
<el-card style="height: 100vh">
<div style="height: 92vh; overflow: auto">
<v-form-designer style="height: 98vh; position: relative; top: -48px"
:designer-config="designerConfig"
ref="vFormDesigner"></v-form-designer>
</div>
<span class="width_center mb10" style="bottom: 0">
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="getFormJson"> </el-button>
</span>
</el-card>
</template>

<script>
export default {
name: "vFormEdit",
data() {
return {
designerConfig: {
//是否显示GitHub、文档等外部链接
externalLink: false,

//是否显示导入JSON按钮
importJsonButton: true,

//是否显示导出JSON器按钮
exportJsonButton: false,

//是否显示导出代码按钮
exportCodeButton: false,

//是否显示生成SFC按钮
generateSFCButton: false,
},
obj: {}
}
},
methods: {
getFormJson() {
this.obj.type = true
this.obj.formJson = JSON.stringify(this.$refs.vFormDesigner.getFormJson())
if (this.$refs.vFormDesigner.getFormJson().widgetList.length) {
console.log(this.obj)
window.parent.postMessage(this.obj, '*');
this.$refs.vFormDesigner.clearDesigner()
} else {
this.$message({
type: 'error',
message: '请编辑报表模板'
})
}
},
cancel() {
// 清空画布
this.$refs.vFormDesigner.clearDesigner()
this.obj.type = false
window.parent.postMessage(this.obj, '*');
}
},
mounted() {
window.addEventListener('message', messageEvent => {
// console.log(messageEvent,'messageEvent---------------')
if (messageEvent.source !== window.parent.window.parent) return;
// console.log('子收到messageEvent:',messageEvent);
console.log('儿子收到vue的数据:', messageEvent.data);
if (messageEvent.data.formJson) {
this.$refs.vFormDesigner.setFormJson(JSON.parse(messageEvent.data.formJson))
}

})
}
}
</script>

<style scoped>

</style>

三、父组件

1、在你的父组件中引入iframe;
2、使用iframeWin.postMessage发送参数;
3、使用window.addEventListener()获取并监听iframe传递来的数据;

<template>
<el-drawer :visible.sync="drawer"
:direction="direction"
size="85%"
style="margin-top: -70px"
:before-close="handleClose">
<iframe src="http://localhost:80/#/vForm"
style="width: 100%; height: 100%; border: 0; margin: 0"
ref="iframe" @load="loader"></iframe>
</el-drawer>
</template>

<script>
export default {
name: "reportAdd",
data(){
return{
direction: 'rtl',
drawer:false,
form:{
formJson:''
}
}
},
methods:{
handleClose(done) {
this.$confirm('确认关闭?')
.then(_ => {
done();
})
.catch(_ => {});
},
loader() {
// 传参
const mapFrame = this.$refs['iframe'];
const iframeWin = mapFrame.contentWindow;
iframeWin.postMessage(
{
formJson: this.form.formJson || '',
},
'*'
);
}
},
mounted() {
// 获取并监听iframe传递来的数据
let that = this
window.addEventListener('message', function (e) {
let res = e.data || {};
console.log(res)
if(res.type) {
that.form.formJson = res.formJson || ''
}
that.drawer = false
})
}
}
</script>

<style lang="scss">
body {
margin: 0; /* 如果页面出现垂直滚动条,则加入此行CSS以消除之 */
}

</style>

四、使用postMessage来实现父子通信跨域

1、子向父通信

parent父组件:

window.addEventListener('message', function (e) {
let res = e.data || {};
//自己的逻辑业务处理
})

child子组件:

window.parent.postMessage(this.obj, '*');

2、父向子通信

parent父组件:

loader() {
const mapFrame = this.$refs['iframe'];//获取iframe
const iframeWin = mapFrame.contentWindow;
iframeWin.postMessage(
{
formJson: this.form.formJson || '',
},
'*'
);//*是子页面的源(协议+主机+端口号)
}

child子组件:

window.addEventListener('message', function(e){
console.log(e.data.data);
}

注意:
1.子向父,子postMessage,父监听message;
2.父向子,父postMessage,子监听message;
3.测试发现,子向父postMessage的时候,源可以写为‘*’,父向子postMessage的时候,源需要写成子的源,(也就是子页面的协议+主机号+端口)