最近在項目上有個移動端(uni-app)的需求,就是要在移動端APP上的vue頁面中通過web-view組件來調(diào)用html頁面,并且要實現(xiàn)在html頁面中可以點擊一個元素來調(diào)用vue頁面中uni的API(掃碼接口),同時也可以在vue頁面中也可以調(diào)用html頁面中的js函數(shù)并進行傳參。
1. HBuilderX版本:2.8.11.20200907
2. V3編譯器
引用依賴的文件
在 web-view 加載的 HTML 中調(diào)用 uni 的 API,需要在 HTML 中引用必要的 JS-SDK
<script type="text/javascript" src="//js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
注意:這些 JS 文件是在 web-view 加載的那個 HTML 文件中引用的,而不是 uni-app 項目中的文件。
監(jiān)聽 web-view 的 message 事件
監(jiān)聽 web-view 組件的 message 事件,然后在事件回調(diào)的 event.detail.data 中接收傳遞過來的消息。
<template>
<view>
<web-view src="http://192.168.1.1:3000/test.html" @message="handleMessage"></web-view>
</view>
</template>
<script>
export default {
methods: {
handleMessage(evt) {
console.log('接收到的消息:' + JSON.stringify(evt.detail.data));
}
}
}
</script>
調(diào)用的時機
在引入上面的依賴文件后,需要在HTML中監(jiān)聽UniAppJSBridgeReady,事件觸發(fā)后,
才能安全調(diào)用uni的API。
<script type="text/javascript" src="//js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
<script>
document.querySelector('.btn-list').addEventListener('click', function(evt) {
var target = evt.target;
if (target.tagName === 'BUTTON') {
var action = target.getAttribute('data-action');
if(action === 'navigateTo') {
uni.postMessage({
data: {
action: 'postMessage'
}
});
}
}
});
</script>
上面代碼的意思就是在html頁面中點擊按鈕列表中的某個按鈕,
觸發(fā)了uni.postMessage接口,進而調(diào)用了vue頁面methods中的handleMessage方法,
并將參數(shù)data傳給了vue頁面。
在vue頁面中調(diào)用html頁面的js函數(shù)
示例代碼:
var currentWebview = this.$mp.page.$getAppWebview().children()[0];
currentWebview.evalJS("htmljsfuc('"+res.result+"')");
其中的htmljsfuc就是要在html頁面中定義的js函數(shù)。
完整代碼示例:
父組件向子組件傳值的方法很簡單,就一句話。vue父組件向子組件傳值的方法:必須使用props屬性來定義父組件傳遞過來的數(shù)據(jù),然后把父組件里的數(shù)據(jù)傳遞到子組件中就行了。
1.請看下面這個例子,你就懂了
<!Doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GBK"/> <title>vue父組件向子組件傳值方法</title> </head> <body> <div id="app"> <son :finfo="msg"></son> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var vm = new Vue({ el: '#app', data: { msg: '我是父組件里的消息' }, components: { son: { template: '<h1>我是子組件 --- {{finfo}}</h1>', props: ['finfo'] } } }); </script> </body> </html>
2.結(jié)果如下:
除注明外的文章,均為來源:老湯博客,轉(zhuǎn)載請保留本文地址!
原文地址:http://tangjiusheng.com/vue/170.html
賬號為華為云開發(fā)者社區(qū)官方運營賬號,提供全面深入的云計算前景分析、豐富的技術(shù)干貨、程序樣例,分享華為云前沿資訊動態(tài)
本文分享自華為云社區(qū)《【Vue棘手問題解決】項目實現(xiàn)JS向Vue傳值》,原文作者:SHQ5785 。
項目開發(fā)過程中,組件通過render()函數(shù)渲染生成,并在組件內(nèi)部定義了自定義拖拽指令。自定義拖拽指令規(guī)定了根據(jù)用戶可以進行元素拖拽、縮放等一系列邏輯處理的動作。
另一個邏輯處理頁面由Vue實現(xiàn),該頁面可以實時展示元素相關(guān)屬性信息(包括size、width、height及l(fā)eft、top等屬性)。
1. 監(jiān)聽器方式實現(xiàn);
2. Vuex state實現(xiàn);
.js
// 鼠標按下事件
el.onmousedown = function (e) {
...
document.onmouseup = function (e) {
document.body.style.cursor = 'pointer';
document.onmousemove = null;
document.onmouseup = null;
isMove = false;
document.body.removeChild(mask);
// 元素樣式relative下方位屬性
let domStyle = {
width: data.width,
height: data.height,
left: data.left,
top: data.top
}
el.style.cssText = setStyle(el, domStyle)
// Vuex state實現(xiàn)方式
store.commit('domAzimuth/SET_DOMAZIMUTION', el.style.cssText);
// 監(jiān)聽器實現(xiàn)方式
// window.postMessage({domStyle: domStyle}, '*')
}
}
.vue
computed: {
...mapGetters('dragModule', ['editLayer']),
...mapGetters('domAzimuth', ['directProps']),
domStyle () {
return this.directProps
}
},
// 監(jiān)聽器方式中,務(wù)必在頁面銷毀前釋放掉監(jiān)聽器,否則會造成內(nèi)存泄漏!
beforeDestroy () {
// window.removeEventListener('message', this.listenerMessage)
},
mounted () {
// window.addEventListener('message', this.listenerMessage)
},
watch: {
domStyle (n) {
let configs = []
let model = {}
for (let name in this.editSoul.model) {
let config = this.editSoul.model[name]
model[name] = ''
config.name = name
if ('style' === name) {
config.value = this.directProps
}
configs.push(config)
}
this.model = model
this.configs = configs
},
}
在Vue項目優(yōu)化過程中,頁面部分應(yīng)用JS調(diào)用promise返回的異步數(shù)據(jù),導(dǎo)致頁面部分始終無法加載后臺返回的數(shù)據(jù)值。通過觸發(fā)其他DOM操作(例如折疊欄位的操作),后臺數(shù)據(jù)可以正常渲染展示。處理邏輯大致如下:
<template>
<div v-for="(items, index) in results" :key="items.itemsID">
<span v-for="(item, index) in items.appendItems" :key="item.itemID">
<el-button type="text" @click="handlerClick(item)">
{{item.itemName}}
</el-button>
</span>
</div>
</template>
<script>
results.foreach((result, index, results) => {
results[index].appendItems = []
aysnMethods(inputParams).then(res => {
results[index].appendItems = res.returnResults
})
})
</script>
經(jīng)過頁面數(shù)據(jù)輸出及debugger斷點調(diào)試,發(fā)現(xiàn)在頁面渲染結(jié)束前,異步數(shù)據(jù)并未處理完畢,導(dǎo)致頁面數(shù)據(jù)渲染問題。
當vue實例生成后,再次給對象賦值時,并不會自動更新到視圖上去; 當我們?nèi)タ磛ue文檔的時候,會發(fā)現(xiàn)有這么一句話:如果在實例創(chuàng)建之后添加新的屬性到實例上,它不會觸發(fā)視圖更新。
受 ES5限制,Vue.js不能檢測到對象屬性的添加或刪除,即Vue未做到臟數(shù)據(jù)檢查。因為 Vue.js
在初始化實例時將屬性轉(zhuǎn)為 getter/setter,所以屬性必須在 data對象上才能讓 Vue.js轉(zhuǎn)換它,才能讓它是響應(yīng)的。
通過以上問題分析,可通過v-if控制頁面渲染、銷毀邏輯,在異步方法請求前銷毀相應(yīng)數(shù)據(jù)段,異步方法請求成功后新建相應(yīng)數(shù)據(jù)段。
代碼如下:
<template>
<div v-if="showForm">
<div v-for="(items, index) in results" :key="items.itemsID">
<span v-for="(item, index) in items.appendItems" :key="item.itemID">
<el-button type="text" @click="handlerClick(item)">
{{item.itemName}}
</el-button>
</span>
</div>
</div>
</template>
<script>
data(): {
return {
showForm: false
}
}
results.foreach((result, index, results) => {
results[index].appendItems = []
vm.showForm = false
aysnMethods(inputParams).then(res => {
results[index].appendItems = res.returnResults
vm.showForm = false
})
})
</script>
點擊關(guān)注,第一時間了解華為云新鮮技術(shù)~
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。