前言
记录一下关于在vue中嵌套多个iframe时,如何进行vue文件和iframe的数据通信,并通过src实现动态切换不同的iframe。
一、文件结构
1、router
const routes = [
{
path: '/',
redirect: '/parent',
},
{
path: '/parent',
name: 'parent',
component: parent,
},
{
path: '/children',
name: 'children',
component: children,
},
{
path: '/children2',
name: 'children2',
component: children2,
},
]
2、parent.vue
<template>
<div>
<div class="title">
<button @click="btn">提交</button>
<button @click="change1">切换children1</button>
<button @click="change2">切换children2</button>
<div>{{ childrenInfo }}</div>
<div>{{ save }}</div>
</div>
<div class="box" id="iframeBox">
<!-- <iframe
id="iframeId"
src="http://192.168.1.8:8080/children"
width="100%"
height="100%"
marginwidth="0"
marginheight="0"
frameborder="0"
></iframe> -->
</div>
</div>
</template>
<script>
export default {
name: 'parent',
data () {
return {
iframe: '',
iframeBox: '',
save: '',
childrenInfo: '',
preview: ''
}
},
methods: {
btn () {
this.iframeBox = document.querySelector('#iframeBox')
this.iframe = document.createElement('iframe')
this.iframe.onload = () => {
console.log('加载完成') // 这样每次都会触发
this.iframe.contentWindow.postMessage({ payload: 'iframe参数' }, '*')
}
this.iframe.src = 'http://192.168.1.8:8080/children'
this.iframeBox.appendChild(this.iframe)
},
change1 () {
this.iframe.src = 'http://192.168.1.8:8080/children'
},
change2 () {
this.iframe.src = 'http://192.168.1.8:8080/children2'
}
},
mounted () {
// 向iframe发送信息
this.iframeBox = document.querySelector('#iframeBox')
this.iframe = document.createElement('iframe')
this.iframe.onload = () => {
console.log('加载完成') // 这样每次都会触发
this.iframe.contentWindow.postMessage({ payload: 'iframe参数' }, '*')
}
this.iframe.src = 'http://192.168.1.8:8080/children'
this.iframeBox.appendChild(this.iframe)
// 监听子页面想父页面的传参
window.addEventListener('message', (event) => {
// 此处执行事件
console.log('监听到子页面的传参[eltabs页面][formdata数据监听 ]')
if (event.data.typeAction === 'save') {
this.save = event.data.typeAction
this.childrenInfo = '这是iframe页面传递过来的参数'
}
if (event.data.typeAction === 'preview') {
this.save = event.data.typeAction
this.childrenInfo = '这是iframe【2】页面传递过来的参数'
}
})
}
}
</script>
<style scoped>
.title {
height: 100px;
border: 1px solid red;
}
.box {
width: 100%;
border: 1px solid red;
}
</style>
3、children.vue
<template>
<div class="iframe">
<div>iframe页面</div>
<div>parent页面传递的参数:{{ parentData }}</div>
<button @click="btn">向parent文件传递参数</button>
</div>
</template>
<script>
export default {
name: 'parent',
data () {
return {
parentData: ''
}
},
methods: {
btn () {
window.parent.postMessage({ typeAction: 'save' }, '*')
}
},
mounted () {
// 监听父组件传递过来的参数
window.addEventListener('message', (event) => {
console.log(event);
// 此处执行事件
console.log(event.data, '监听到vue页面的传参[iframe页面][操作类型数据监听 ]')
if (event.data.payload) {
this.parentData = event.data.payload
}
})
}
}
</script>
<style scoped>
.iframe {
border: 2px solid blue;
}
</style>
4、children2.vue
<template>
<div class="iframe">
<div>iframe【2】页面</div>
<div>parent页面传递的参数:{{ parentData }}</div>
<button @click="btn">向parent文件传递参数</button>
</div>
</template>
<script>
export default {
name: 'parent',
data () {
return {
parentData: ''
}
},
methods: {
btn () {
window.parent.postMessage({ typeAction: 'preview' }, '*')
}
},
mounted () {
// 监听父组件传递过来的参数
window.addEventListener('message', (event) => {
console.log(event);
// 此处执行事件
console.log(event.data, '监听到vue页面的传参[iframe【2】页面]')
if (event.data.payload) {
this.parentData = event.data.payload
}
})
}
}
</script>
<style scoped>
.iframe {
border: 2px solid blue;
}
</style>
二、iframe使用的一些坑
1、iframe.onload不生效
一定要注意iframe绑定事件和加载时的顺序,先绑定事件再赋值src地址,才会每次都会触发onload。
另外,不要在<template>
中写iframe
,最好通过动态创建的方式。
2、iframe监听出现2次事件
{type: ‘webpackInvalid’, data: undefined}
或者
{type: ‘webpackOk’, data: undefined}
具体出现的原因不清楚。
但可以判断event.data.payload
是否存在,来保存正确数据。payload
是传递的参数对象
3、tabs标签页嵌套不同iframe情况
可以通过切换iframe.src
来实现
三、小技巧
1、以上方法仍无法进行数据通信的解决方案
如果iframe仍然无法正常的通信,可以考虑用下本地缓存来传递数据,这个也是可以的,已验证。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84946.html