前段時間 使用h5搞了個用cesium.js做的地圖服務功能,后來想整合到vue項目,當然最簡單的就是iframe直接拿來用了。
但html和vue的方法交互就是成了問題,vue調用html種方法還好,尤其是html調用vue中的方法當初就沒有解決,忙着項目上線直接搞了個setInterval不停輪詢,哎不說他了;
現在空點了來把問題解決了,俗話說得好閑時學來忙時用,閑時不學忙時莫得用,所以各位走過路過的朋友看過來看過來,要買鄉音這邊來(程序員改擺地攤了,哈哈哈)。且扯遠了下面進入主題
一、 vue調用html中方法
這個還是挺簡單的 直接window.frames['iframe name'].方法名
如:
invokeHtmlMethod() {
window.frames['iframeMap'].lodaTable()
},
二、html調用vue中方法
這個就有點難做了(准確來說是采坑了);第一個當然會想到直接將方法綁到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!');
}
’試試。。咦;OK了
五、兩個項目比對,找出錯誤
奇葩的是吧代碼拷貝到原來的那個項目運行依然報錯;
剛開始以為是cesium影響了,我就新建個頁面來試試;還是不對;
又想到是不是element ui影響了,我又到新建的項目(不報錯的這個項目)里去也把element ui 也安裝上,但是運行依然可以;
這初步排除了並不是這兩者影響造成的錯誤;調來調去始終就是不行,
難道是項目搭建的有問題??這個也不大可能呀;
執着的我就不信還找不到問題所在;
最后吧兩個項目代碼一比對:才發現是自己疏忽了,看下面代碼
不要意思帶大家繞了這么大一圈,是這該死的單詞create
、created
(一個一般現在時,一個過去式)區別就這么大~
哎,有時候自己給自己挖個坑,可能比別人挖得坑還要難爬出啦
六、完整實例
好了問題終於解決了,完整代碼如下
vue頁面
<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頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button onclick="invockIframeMethod()">點擊調用iframe</button>
<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>
最后運行結果
都是你的錯~粗心惹的禍,記錄記錄。