前段时间 使用h5搞了个用cesium.js做的地图服务功能,后来想整合到vue项目,当然最简单的就是iframe直接拿来用了。
但html和vue的方法交互就是成了问题,vue调用html种方法还好,尤其是html调用vue中的方法当初就没有解决,忙着项目上线直接搞了个setInterval不停轮询,哎不说他了;
现在空点了来把问题解决了,俗话说得好闲时学来忙时用,闲时不学忙时莫得用,所以各位走过路过的朋友看过来看过来,要买乡音这边来(程序员改摆地摊了,哈哈哈)。且扯远了下面进入主题
这个还是挺简单的 直接window.frames['iframe name'].方法名
如:
invokeHtmlMethod() {
window.frames['iframeMap'].lodaTable()
},
这个就有点难做了(准确来说是采坑了);第一个当然会想到直接将方法绑到window上了;
create(){
window.vueDefinedMyProp = (receiveParams) => {
this.receiveParamsFromHtml(receiveParams)
}
},
methods: {
receiveParamsFromHtml(res){
console.log(res)
},
}
然后html页面中是这样
<script>
function invockIframeMethod() {
window.parent['vueDefinedMyProp']('you are Superman!');
}
</script>
运行报错了
VM345:1 Uncaught TypeError: window.parent.vueDefinedMyProp is not a function
at <anonymous>:1:15
后来去网上看见这朋友是这么做得
博客地址 https://www.cnblogs.com/xiangsj/p/5895917.html
于是我就照着改了试试;
data(){
return: {
randomObj: {
edit: 'edit_' + new Date().getTime() // 先定义随机ID
}
}
},
created() {
let _this = this;
//这里可放到全局,提供给子 iframe 调用
window[this.randomObj.edit] = (_this) => {
this.receiveParamsFromHtml(_this) //VUE 中方法
}
},
methods: {
receiveParamsFromHtml(res){
console.log(res)
},
}
html页面是这样
function invockIframeMethod() {
var fatherId = null
window.parent[fatherId.edit]('you are Superman!');
}
不行报错的;;;,
最后没办法,俺新建一个项目
将代码 改成这样
data(){
},
created() {
// 初始化时为window绑定一个方法
window['vueDefinedMyProp'] = (receiveParams) => {
this.receiveParamsFromHtml(receiveParams)
}
},
methods: {
receiveParamsFromHtml(res){
console.log(res)
},
}
html页面改成这样
function invockIframeMethod() {
// 是用widow调用vue绑定的vueDefinedMyProp方法
window.parent['vueDefinedMyProp']('you are Superman!');
}
奇葩的是吧代码拷贝到原来的那个项目运行依然报错;
刚开始以为是cesium影响了,我就新建个页面来试试;还是不对;
又想到是不是element ui影响了,我又到新建的项目(不报错的这个项目)里去也把element ui 也安装上,但是运行依然可以;
这初步排除了并不是这两者影响造成的错误;调来调去始终就是不行,
难道是项目搭建的有问题??这个也不大可能呀;
执着的我就不信还找不到问题所在;
最后吧两个项目代码一比对:才发现是自己疏忽了,看下面代码
不要意思带大家绕了这么大一圈,是这该死的单词create
、created
(一个一般现在时,一个过去式)区别就这么大~
哎,有时候自己给自己挖个坑,可能比别人挖得坑还要难爬出啦
好了问题终于解决了,完整代码如下
<template>
<button @click="invokeHtmlMethod">调用html种方法</button>
<div class="iframestyleset">
<iframe name = "iframeMap" id="iframeMapViewComponent" v-bind:src="getPageUrl"
width="100%" height="100%"
frameborder="0" scrolling="no" ref="iframeDom"
></iframe>
</div>
</template>
export default {
data() {
return {
getPageUrl: 'static/testMsgWithIframe.html'
}
},
created() {
// 初始化时为window绑定一个方法
window['vueDefinedMyProp'] = (receiveParams) => {
this.receiveParamsFromHtml(receiveParams)
}
},
methods: {
receiveParamsFromHtml(res) {
console.log(res)
},
invokeHtmlMethod() {
window.frames['iframeMap'].lodaTable()
},
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<button onclick="invockIframeMethod()">点击调用iframebutton>
<script>
function invockIframeMethod() {
// 是用widow调用vue绑定的vueDefinedMyProp方法
window.parent['vueDefinedMyProp']('you are Superman!');
}
function lodaTable() {
let num = 10;
while (num>0){
console.log(`number : ${num}`);
num--;
}
}
script>
body>
html>
都是你的错~粗心惹的祸,记录记录。