关于Vue中使用iframe并进行数据通信

导读:本篇文章讲解 关于Vue中使用iframe并进行数据通信,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

前言

记录一下关于在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

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!