uni-app在web-view加载的本地及远程HTML中调用uni的API及实现网页和vue页面通讯
uni-app在web-view加载的本地及远程HTML中调用uni的API及实现网页和vue页面通讯
uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。
在web-view加载页面中,会涉及wx、plus、uni等对象的使用。
- 在小程序下使用wx的api,需要引入微信提供的https://res.wx.qq.com/open/js/jweixin-1.4.0.js。
- 不管是在小程序下还是在app下,使用uni的api,需要引入https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js
本文会详述在webview里的uni对象的使用方式,以及和vue页面的通讯方式。
HBuilderX 1.0.0 版本开始,uni-app 支持在 web-view 中调用 uni 的 API。
引用依赖的文件
在 web-view 加载的 HTML 中调用 uni 的 API,需要在 HTML 中引用必要的 JS-SDK。
<!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<!-- uni 的 SDK,必须引用。 -->
<script type="text/javascript" src="//js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
Tips
- 这些 JS 文件是在 web-view 加载的那个 HTML 文件中引用的,而不是 uni-app 项目中的文件。
- 如果不考虑微信小程序,则无需引入微信的 JS-SDK。
- 两个文件同时引入时,注意引入的顺序,微信的需要在前。
调用的时机
在引用依赖的文件后,需要在 HTML 中监听 UniAppJSBridgeReady 事件触发后,才能安全调用 uni 的 API。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
});
页面跳转
支持调用所有的 uni 路由方法,可以实现从 HTML 重新跳转回应用内的页面。
在 UniAppJSBridgeReady 后,调用路由方法跳转到应用内的页面。
document.addEventListener('UniAppJSBridgeReady', function() {
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.navigateTo({
url: '/pages/component/button/button'
});
}
}
});
});
发送消息
可以通过 uni.postMessage 在 HTML 中向应用发送消息。要实现此功能,需要完成以下两步工作。
监听 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 向应用发送消息
uni.postMessage 中的参数格式,必须是 data: {}。也就是说,传递的消息信息必须在 data 这个对象中。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.postMessage({
data: {
action: 'postMessage'
}
});
});
每次执行 postMessage 后,传递的消息会以数组的形式存放。因此,在 web-view 的 message 事件回调中,接收到的 event.detail.data 的值是一个数组。
获取当前环境信息
HTML 在不同的环境下,可能需要执行不同的操作或传递不同的消息。可以通过 uni.getEnv() 方法,来获取当前的环境信息。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
if (res.plus) {
console.log('当前环境为【5+App】');
} else if (res.miniprogram) {
console.log('当前环境为【微信小程序】');
}
});
});
本地 HTML
自 HBuilderX v1.1.0 起,在 5+App 平台下 web-view 支持加载应用内的 HTML 资源。
本地的 HTML 资源,必须存放在规定的目录下,即 uni-app 项目->hybrid->html 目录。
├─common
├─components
├─hybrid
│ └─html
│ test.html
├─pages
├─static
│ App.vue
│ main.js
│ manifest.json
│ pages.json
与 html 文件相关的 css、js 等本地资源,同样放在这个 hybrid->html 目录下。
这个hybrid目录不会被编译器编译,所以这里的不能放vue文件,而其他目录也不能放本地HTML文件。
注意:在本地 HTML 中引入网络资源时,必须补全协议。比如:https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js
运行体验
示例中 web-view 加载的是一个本机的测试地址,这个测试 HTML 见附件。
在uni-app中,通过web-view
组件加载本地或远程HTML时,实现调用uni的API以及网页与Vue页面之间的通讯,可以通过以下方式实现。这里主要涉及到postMessage
API进行通讯,并结合uni-app的特定方法。
1. 在Vue页面中设置web-view
组件
首先,在Vue页面中嵌入web-view
组件,并指定加载的HTML地址(可以是本地文件路径或远程URL)。
<template>
<view>
<web-view :src="webViewSrc" @message="handleMessage"></web-view>
<button @click="sendMessageToWebView">发送消息到WebView</button>
</view>
</template>
<script>
export default {
data() {
return {
webViewSrc: 'path/to/local/file.html' // 或 'https://example.com/remote.html'
};
},
methods: {
sendMessageToWebView() {
// 发送消息到webView,使用#postMessage方法
const message = {
type: 'fromVue',
data: 'Hello from Vue!'
};
uni.createSelectorQuery().select('#webview').node().exec((res) => {
const webviewContext = res[0].node;
webviewContext.evalJS(`window.postMessage(${JSON.stringify(message)}, '*');`);
});
},
handleMessage(event) {
const { data } = event.detail;
console.log('Received message from WebView:', data);
}
}
};
</script>
2. 在HTML页面中接收和发送消息
在HTML页面中,通过window.addEventListener
监听message
事件来接收来自Vue页面的消息,并使用window.postMessage
发送消息回Vue页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebView Content</title>
</head>
<body>
<h1>Hello from WebView</h1>
<script>
window.addEventListener('message', (event) => {
const { data } = event.data;
console.log('Received message from Vue:', data);
// 发送消息回Vue页面
window.parent.postMessage({
type: 'fromWebView',
data: 'Hello from WebView!'
}, '*');
});
</script>
</body>
</html>
注意事项
- 确保
web-view
组件的src
属性正确指向本地或远程HTML文件。 - 在发送消息时,使用
uni.createSelectorQuery().select('#webview').node().exec
获取web-view
的上下文,然后通过evalJS
执行JavaScript代码。这里的#webview
是web-view
组件的ID,如果没有设置ID,可以省略select('#webview')
部分。 - 通讯过程中,注意安全性,特别是在处理来自不同源的消息时,验证消息来源和内容。
通过上述代码,你可以在uni-app中实现web-view
加载的HTML与Vue页面之间的双向通讯。