前言

  项目需要,我需要引入一个已经封装好的浏览器插件。插件只能以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>

结尾

  学无止境,还是有很多不知道的,继续精进技术。。。

  欢迎大家沟通交流。

01-06 06:07