vue项目iframe的传值问题
- 2019 年 11 月 21 日
- 筆記
前言
项目需要,我需要引入一个已经封装好的浏览器插件。插件只能以html的方式调用,
所以。我把插件的使用封装了一个html页面。vue项目则利用iframe的方式引入。
到这里我就遇到了一个问题,那就是vue项目中iframe的传值问题,这里做个笔记防止之后忘记,
如果有其他的方式,欢迎大家交流,不胜感激。
正文
先写几个简易的demo
需要用到的html
<!DOCTYPE html> <html lang="en" style="height: 100%;"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title>测试damo</title> </head> <body> <noscript> <strong>请使用支持javascript的浏览器</strong> </noscript> <div id="app">1213123111220980980</div> <button onclick="setData()">打印本地的值</button> <button onclick="getData()">点击获取值vue的值</button> </body> <script> var wpsData; var aaaaa = '22222' function setData(){ alert(aaaaa) } function getData(){ alert(wpsData) } </script> </html>
父级页面用iframe调用html
<template> <div> <div>在线文档编译组件</div> <el-button @click="getData()">点击获取iframe数据</el-button> <el-button @click="setData('我是vue数据')">向iframe中发送数据</el-button> <iframe id="mainIframe" ref="mainIframe" name="mainIframe" src="./test.html" frameborder="0" scrolling="auto" @load="loaded" /> </div> </template> <script> export default { name: 'wps-edit', props: { }, mounted() { }, methods: { getData() { }, setData(data) { } } } </script> <style lang="scss" scoped></style>
这里提供两种传值方式:
第一种:postMessage
1、父页面生命周期函数中
const mapFrame = this.$refs['mainIframe'] if (mapFrame.attachEvent) { // 兼容浏览器判断 mapFrame.attachEvent('onload', function() { const iframeWin = mapFrame.contentWindow iframeWin.postMessage('初始化值', '*') // data传递的参数 *写成子页面的域名或者是ip }) } else { mapFrame.onload = function() { const iframeWin = mapFrame.contentWindow iframeWin.postMessage('初始化值', '*') } }
2、html页面接受数据
window.addEventListener('message', function(messageEvent) { var data = messageEvent.data; console.log('收到vue的数据:',data); wpsData = data console.log('wpsData:',wpsData); }, false);
在页面加载结束,你就能发现html页面中的wpsData值已经被改变成了父级页面传过来的值。
这种方式是加载一次,数据不能实时同步,或者我没有实时同步数据的方法
第二种:直接操作iframe
1、父级页面直接给iframe的window对象设置值
setData(data) { const obj1 = window.frames['mainIframe']// 获得对应iframe的window对象 obj1.wpsData = '设置的数据' }
2、父级页面设置完值后,在html页面直接打印对应的参数,此时会发现wpsData数据已经改变
function getData(){ alert(wpsData) }
这种方式每次在父级页面改变值,html页面就会实时更新数据,我暂时用的这种方式,至于有什么bug,我正在研究。
完整的页面代码
html页面
<!DOCTYPE html> <html lang="en" style="height: 100%;"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title>测试damo</title> </head> <body> <noscript> <strong>请使用支持javascript的浏览器</strong> </noscript> <div id="app">1213123111220980980</div> <button onclick="setData()">打印本地的值</button> <button onclick="getData()">点击获取值vue的值</button> </body> <script> var wpsData; window.addEventListener('message', function(messageEvent) { var data = messageEvent.data; console.log('收到vue的数据:',data); wpsData = data console.log('wpsData:',wpsData);var aaaaa = '22222' function setData(){ alert(aaaaa) } function getData(){ alert(wpsData) } </script> </html>
父级页面
<template> <div> <div>在线文档编译组件</div> <el-button @click="getData()">点击获取iframe数据</el-button> <el-button @click="setData('我是vue数据')">向iframe中发送数据</el-button> <iframe id="mainIframe" ref="mainIframe" name="mainIframe" src="./test.html" frameborder="0" scrolling="auto" @load="loaded" /> </div> </template> <script> // 工具类 export default { name: 'wps-edit', props: { }, mounted() { const mapFrame = this.$refs['mainIframe'] if (mapFrame.attachEvent) { // 兼容浏览器判断 mapFrame.attachEvent('onload', function() { const iframeWin = mapFrame.contentWindow iframeWin.postMessage('初始化值', '*') // data传递的参数 *写成子页面的域名或者是ip }) } else { mapFrame.onload = function() { const iframeWin = mapFrame.contentWindow iframeWin.postMessage('初始化值', '*') } } }, methods: { loaded() { const vm = this.$refs.mainIframe.contentWindow.vm console.log(vm) // vm.func1() }, getData() { const obj1 = window.frames['mainIframe']// 获得对应iframe的window对象 alert(obj1.aaaaa) }, getWpsData() { return 'wps数据' }, setData(data) { const obj1 = window.frames['mainIframe']// 获得对应iframe的window对象 obj1.wpsData = '设置的数据' } } } </script> <style lang="scss" scoped></style>
结尾
学无止境,还是有很多不知道的,继续精进技术。。。
欢迎大家沟通交流。