文章目录
Vue内嵌iframe及通讯,消息交互方式
1. 父向子传递消息
vue3.0: window.frames[0].postMessage();
vue2.0: iframeEl.contentWindow.postMessage
2. 子接收父消息:
window.addEventListener(‘message’)
3. 子向父传递消息:
window.parent.postMessage
4. 父接收子消息:
window.addEventListener(‘message’)
代码渲染效果图
iframeDemo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.iframeBox {
width: 100%;
height: 200px;
border: 2px solid #bfbfbf;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="iframeBox">
<button id="sendBtn">我是iframe页面按钮</button>
<div id="message"></div>
</div>
</body>
</html>
<script type="text/javascript">
// iframe页面点击发送按钮,传递事件给vue
document.getElementById("sendBtn").addEventListener("click", () => {
window.parent.postMessage({
data: {
code: "success",
test: "我是点击iframe页面按钮后过来的数据"
}
}, '*');
});
// 监听vue页面传来的message事件
window.addEventListener("message", (event) => {
const data = event.data
if (data.code === 'success') {
console.log(data); // {code: 'success', test: '我是点击vue页面按钮后过来的数据!'}
document.getElementById("message").innerText = data.test;
}
}, false);
</script>
<style>
</style>
vueDemo.vue (vue3.0)
<template>
<div class="home">
<iframe src="/iframeDemo.html" ref="iframeWin" frameborder="0" width="100%" height="400px" />
<el-button @click="btnClick">我是vue页面按钮</el-button>
<div>{{ message }}</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from "vue";
const message = ref('');
function btnClick() {
const iframeWindow = window.frames[0]; // 获取iframe的window对象
iframeWindow.postMessage(
{
code: 'success',
test: '我是点击vue页面按钮后过来的数据!',
},
'*'
)
}
onMounted(() => {
nextTick(() => {
const iframeWindow = window.frames[0]; // 获取iframe的window对象
})
window.addEventListener('message', (event) => {
const data = event.data.data
if (data.code === 'success') {
console.log(data, 'vue'); // {code: 'success', test: '我是点击iframe页面按钮后过来的数据'}
message.value = data.test
}
})
})
</script>
<style scoped>
.home {
width: 890px;
height: 100%;
border: #ff3333 solid 8px;
box-sizing: border-box;
box-sizing: border-box;
padding: 20px;
}
</style>
vueDemo.vue (vue2.0)
<template>
<div class="home">
<iframe src="/iframeDemo.html" ref="iframe" frameborder="0" width="100%" height="400px" />
<el-button @click="btnClick">我是vue页面按钮</el-button>
<div>{{ message }}</div>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
},
methods: {
// 给iframe发送事件
btnClick() {
this.iframeWin.postMessage(
{
code: 'success',
test: '我是点击vue页面按钮后过来的数据!',
},
'*'
)
},
},
mounted() {
// 监听iframe页面点击按钮触发事件
window.addEventListener('message', (event) => {
const data = event.data.data
if (data.code === 'success') {
console.log(data, 'vue'); // {code: 'success', test: '我是点击iframe页面按钮后过来的数据'}
this.message = data.test;
}
})
this.iframeWin = this.$refs.iframe.contentWindow
},
}
</script>
<style scoped>
.home {
width: 890px;
height: 100%;
border: #ff3333 solid 8px;
box-sizing: border-box;
box-sizing: border-box;
padding: 20px;
}
</style>
实现 iframe 向 vue 页面通信
- 点击iframe页面,通过 window.parent.postMessage 传递数据到vue页面
- vue页面,通过 window.addEventListener(‘message’) 去接收iframe传递过来的数据
- 实现效果如下(点击iframe页面的按钮事件,在vue页面中监听并console)
- 在 iframeDemo.html 中新建按钮的点击事件
给新建的按钮,设置监听事件// 新建点击按钮 <button id="sendBtn">我是iframe页面按钮</button>
<script type="text/javascript"> // iframe页面点击发送按钮,传递事件给vue document.getElementById("sendBtn").addEventListener("click", ()=> { window.parent.postMessage({ data: { code:"success", test:"我是点击iframe页面按钮后过来的数据" } }, '*'); }); </script>
- 在 vueDemo.vue 页面的 mounted 中监听iframe页面传过来的 message 事件
mounted() { // 监听iframe页面点击按钮触发事件 window.addEventListener('message', (event) => { const data = event.data.data if (data.code === 'success') { console.log(data, 'vue'); // {code: 'success', test: '我是点击iframe页面按钮后过来的数据'} this.message = data.test; } }) // 获取iframe this.iframeWin = this.$refs.iframe.contentWindow },
实现 vue 向 iframe 页面通信
- 点击vue页面,通过 postMessage 传递数据到iframe页面
- iframe页面,通过 window.addEventListener(‘message’) 去接收vue传递过来的数据
-
实现效果如下(点击vue页面的按钮事件,在iframe页面中监听并console)
-
在 vueDemo.html 中新建按钮的点击事件
<el-button @click="btnClick">我是vue页面按钮</el-button>
btnClick() { this.iframeWin.postMessage( { code: 'success', test: '我是点击vue页面按钮后过来的数据!', }, '*' ) },
-
在 iframeDemo.vue 页面的 mounted 中监听iframe页面传过来的 message 事件
// 监听vue页面传来的message事件 window.addEventListener("message", (event) => { const data = event.data if (data.code === 'success') { console.log(data); // {code: 'success', test: '我是点击vue页面按钮后过来的数据!'} document.getElementById("message").innerText = data.test; } }, false);
小结
A页面和B页面之间的通讯也可以用postmessage,请参考添加链接描述