最近在项目上有个移动端(uni-app)的需求,就是要在移动端APP上的vue页面中通过web-view组件来调用html页面,并且要实现在html页面中可以点击一个元素来调用vue页面中uni的API(扫码接口),同时也可以在vue页面中也可以调用html页面中的js函数并进行传参。
1. HBuilderX版本:2.8.11.20200907
2. V3编译器
引用依赖的文件
在 web-view 加载的 HTML 中调用 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 项目中的文件。
监听 web-view 的 message 事件
监听 web-view 组件的 message 事件,然后在事件回调的 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>
调用的时机
在引入上面的依赖文件后,需要在HTML中监听UniAppJSBridgeReady,事件触发后,
才能安全调用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页面中点击按钮列表中的某个按钮,
触发了uni.postMessage接口,进而调用了vue页面methods中的handleMessage方法,
并将参数data传给了vue页面。
在vue页面中调用html页面的js函数
示例代码:
var currentWebview = this.$mp.page.$getAppWebview().children()[0];
currentWebview.evalJS("htmljsfuc('"+res.result+"')");
其中的htmljsfuc就是要在html页面中定义的js函数。
完整代码示例:
父组件向子组件传值的方法很简单,就一句话。vue父组件向子组件传值的方法:必须使用props属性来定义父组件传递过来的数据,然后把父组件里的数据传递到子组件中就行了。
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.结果如下:
除注明外的文章,均为来源:老汤博客,转载请保留本文地址!
原文地址:http://tangjiusheng.com/vue/170.html
账号为华为云开发者社区官方运营账号,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态
本文分享自华为云社区《【Vue棘手问题解决】项目实现JS向Vue传值》,原文作者:SHQ5785 。
项目开发过程中,组件通过render()函数渲染生成,并在组件内部定义了自定义拖拽指令。自定义拖拽指令规定了根据用户可以进行元素拖拽、缩放等一系列逻辑处理的动作。
另一个逻辑处理页面由Vue实现,该页面可以实时展示元素相关属性信息(包括size、width、height及left、top等属性)。
1. 监听器方式实现;
2. Vuex state实现;
.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实现方式
store.commit('domAzimuth/SET_DOMAZIMUTION', el.style.cssText);
// 监听器实现方式
// window.postMessage({domStyle: domStyle}, '*')
}
}
.vue
computed: {
...mapGetters('dragModule', ['editLayer']),
...mapGetters('domAzimuth', ['directProps']),
domStyle () {
return this.directProps
}
},
// 监听器方式中,务必在页面销毁前释放掉监听器,否则会造成内存泄漏!
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项目优化过程中,页面部分应用JS调用promise返回的异步数据,导致页面部分始终无法加载后台返回的数据值。通过触发其他DOM操作(例如折叠栏位的操作),后台数据可以正常渲染展示。处理逻辑大致如下:
<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>
经过页面数据输出及debugger断点调试,发现在页面渲染结束前,异步数据并未处理完毕,导致页面数据渲染问题。
当vue实例生成后,再次给对象赋值时,并不会自动更新到视图上去; 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
受 ES5限制,Vue.js不能检测到对象属性的添加或删除,即Vue未做到脏数据检查。因为 Vue.js
在初始化实例时将属性转为 getter/setter,所以属性必须在 data对象上才能让 Vue.js转换它,才能让它是响应的。
通过以上问题分析,可通过v-if控制页面渲染、销毁逻辑,在异步方法请求前销毁相应数据段,异步方法请求成功后新建相应数据段。
代码如下:
<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>
点击关注,第一时间了解华为云新鲜技术~
*请认真填写需求信息,我们会在24小时内与您取得联系。