121  
查询码:00001100
vue iframe内嵌爬坑
作者: 郁冲冲 于 2020年03月24日 发布在分类 / 人防组 / 人防前端 下,并于 2020年03月24日 编辑
iframe

1、Vue组件中如何引入iframe?

2、vue如何获取iframe对象以及iframe内的window对象?

3、vue如何向iframe内传送信息?

4、iframe内如何向外部vue发送信息?

1、Vue组件中如何引入iframe?

<template> <div class="act-form"> <iframe :src="src"></iframe> </div> </template> <script> export default {
  data () { return { src: '你的src' }
  }
} </script>

如上,直接通过添加iframe标签,src属性绑定data中的src,第一步引入就完成了 

2、vue如何获取iframe对象以及iframe内的window对象?

在vue中,dom操作比不上jquery的$('#id')来的方便,但是也有办法,就是通过ref
<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)
  }
} </script>

然后就是获取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>

3、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>

4、iframe内如何向外部vue发送信息?

现在通过点击“向iframe发送信息”这个按钮,从外部vue中已经向iframe中发送了一条信息

{ cmd: 'getFormJson',
  params: {}
}

那么iframe内部如何处理这个信息呢?

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>iframe Window</title> <style> body { background-color: #D53C2F; color: white;
        } </style> </head> <body> <h1>Hello there, i'm an iframe</h1> <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> <!-- Add "scoped" attribute to limit CSS to this component only --> <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>


 推荐知识

 历史版本

修改日期 修改人 备注
2020-03-24 16:33:50[当前版本] 郁冲冲 1.1.0
2020-03-24 16:32:32 郁冲冲 1.1.1
2020-03-24 16:30:00 郁冲冲 1.1.0

知识分享平台 -V 4.8.7 -wcp