2、vue如何获取iframe对象以及iframe内的window对象?
3、vue如何向iframe内传送信息?
4、iframe内如何向外部vue发送信息?
一、Vue组件中如何引入iframe?
直接通过添加iframe标签,src属性绑定data中的src,第一步引入就完成了
- <template>
- <div class="act-form">
- <iframe :src="src">iframe>
- div>
- template>
-
- <script>
-
- export default {
- data () {
- return {
- src: '你的src'
- }
- }
- }
- script>
二、vue如何获取iframe对象以及iframe内的window对象?
获取iframe的window对象,因为只有拿到这个对象才能向iframe中传值
- <template>
- <div class="act-form">
- <iframe :src="src" ref="iframe">iframe>
- div>
- template>
-
- <script>
-
- export default {
- data () {
- return {
- src: '你的src'
- }
- },
- mounted () {
- // 这里就拿到了iframe的对象
- console.log(this.$refs.iframe)
- // 这里就拿到了iframe的window对象
- console.log(this.$refs.iframe.contentWindow)
- }
- }
- script>
三、vue如何向iframe内传送信息?
通过postMessage,具体关于postMessage是什么,自己去google,
我的理解postMessage是有点类似于UDP协议,就像短信,是异步的,你发信息过去,但是没有返回值的,只能内部处理完成以后再通过postMessage向外部发送一个消息,外部监听message
为了让postMessage像TCP,为了体验像同步的和实现多通信互不干扰,特别制定的message结构如下
- {
- cmd: '命令',
- params: {
- '键1': '值1',
- '键2': '值2'
- }
- }
通过cmd来区别这条message的目的
具体代码如下
- <template>
- <div class="act-form">
- <iframe :src="src" ref="iframe">iframe>
- <div @click="sendMessage">向iframe发送信息div>
- div>
- template>
-
- <script>
-
- export default {
- data () {
- return {
- src: '你的src',
- iframeWin: {}
- }
- },
- methods: {
- sendMessage () {
- // 外部vue向iframe内部传数据
- this.iframeWin.postMessage({
- cmd: 'getFormJson',
- params: {}
- }, '*')
- },
- },
- mounted () {
- // 在外部vue的window上添加postMessage的监听,并且绑定处理函数handleMessage
- window.addEventListener('message', this.handleMessage)
- this.iframeWin = this.$refs.iframe.contentWindow
- },
- handleMessage (event) {
- // 根据上面制定的结构来解析iframe内部发回来的数据
- const data = event.data
- switch (data.cmd) {
- case 'returnFormJson':
- // 业务逻辑
- break
- case 'returnHeight':
- // 业务逻辑
- break
- }
- }
- }
- script>
四、iframe内如何向外部vue发送信息?
现在通过单击‘向iframe发送信息’这个按钮,从外部vue中已经向iframe中发送了一条信息
- {
- cmd: 'getFormJson',
- params: {}
- }
那么iframe内部如何处理这个信息?
- html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>iframe Windowtitle>
- <style>
- body {
- background-color: #D53C2F;
- color: white;
- }
- style>
- head>
- <body>
-
- <h1>Hello there, i'm an iframeh1>
-
- <script>
- // 向父vue页面发送信息
- window.parent.postMessage({
- cmd: 'returnHeight',
- params: {
- success: true,
- data: document.body.scrollHeight + 'px'
- }
- }, '*');
-
- // 接受父页面发来的信息
- window.addEventListener("message", function(event){
- var data = event.data;
- switch (data.cmd) {
- case 'getFormJson':
- // 处理业务逻辑
- break;
- }
- });
- script>
- body>
- html>
至此为止,内部的收发信息和外部的收发信息都已解决!
下面是完整代码:
- <template>
- <div class="act-form">
- <div class="nav">
- <img src="https://cxkccdn.oss-cn-shanghai.aliyuncs.com/lesai_img/icon_back_white.png" @click="back()">
- <div class="title">报名div>
- div>
- <div class="iframe-out">
- <iframe :src="src" ref="iframe" @load="iframeLoad">iframe>
- div>
- <div v-if="isLoaded" class="send-form"><div class="send" @click="sendMessage()">提交div>div>
- div>
- template>
-
- <style lang="sass" rel="stylesheet/sass">
- @import "style.scss";
- style>
-
- <script>
- import { Toast, Indicator } from 'mint-ui'
- import api from '@/utils/api'
-
- export default {
- data () {
- return {
- src: '',
- iframeWin: null,
- isLoaded: false
- }
- },
- created () {
- let matchFamily = this.$store.state.matchFamily
- this.src = process.env.BASE_URL + '/matches/' + matchFamily.match.id + '/act/' + matchFamily.act.id + '/joinweb?token=' + this.$store.state.token
- },
- mounted () {
- window.addEventListener('message', this.handleMessage)
- this.iframeWin = this.$refs.iframe.contentWindow
- // 开启加载动画
- Indicator.open({
- text: '努力加载中...',
- spinnerType: 'triple-bounce'
- })
- },
- methods: {
- back () {
- this.$router.push('/actIntro')
- },
- sendMessage () {
- this.iframeWin.postMessage({
- cmd: 'getFormJson',
- params: {}
- }, '*')
- },
- iframeLoad () {
- // 关闭加载动画
- Indicator.close()
- },
- async handleMessage (event) {
- const data = event.data
- switch (data.cmd) {
- case 'returnFormJson':
- if (data.params.success) {
- // 调用报名方法
- await this.enroll(data.params.data)
- } else {
- console.log('returnFormJson失败')
- console.log(data.params)
- }
- break
- case 'returnHeight':
- if (data.params.success) {
- this.$refs.iframe.height = data.params.data
- this.isLoaded = true
- }
- break
- }
- },
- async enroll (data) {
- let matchFamily = this.$store.state.matchFamily
- let result = await api.enroll(matchFamily.match.id, matchFamily.act.id, data)
- if (result.success) {
- if (result.data.status === 'no_pay') {
- // 更新缓存
- let resultMatch = await api.match(matchFamily.match.id, {})
- if (resultMatch.success) {
- this.$store.commit('SET_CURRENT_MATCH', resultMatch.data)
- }
- Toast({
- message: '报名成功',
- position: 'bottom'
- })
- this.$router.push('/match/' + matchFamily.match.id + '/mdetail')
- } else {
- console.log('需要跳转到支付页面')
- }
- }
- }
- }
- }
- script>