一、React Native简介:
1、React Native采用JavaScript 框架,将 React 基础抽象组件渲染为原生平台UI组件,像View, Text 以及 Image等,可直接映射渲染为对应平台的原生UI组件
2、通过 React 的声明式组件机制和 JavaScript 代码,现有的原生代码和api可以完美地封装嵌合到 React 组件中
3.、React Native创建的原生应用,经常采用混合开发方式嵌入H5
二、React端主要涉及一下方法:
React Native -> Web: The injectedJavaScript prop
React Native -> Web: The injectJavaScript method
Web -> React Native: The postMessage method and onMessage prop
涉及到的主要函数有:onMessage、window.ReactNativeWebView.postMessage、injectedJavaScript、injectJavaScript
1、injectedJavaScript: 在网页第一次加载完成后会立即被Html执行(之后reload都不会再执行),我们需要将这个属性设置为一串js代码段字符串。在这里我们可以如同在html中一样调用页面的的函数。
2、injectJavaScript: RN客户端可以通过webview直接调用这个函数,参数是字符串,调用这个方法后,会在html端以js的方式执行参数中的内容。
3、Html向RN通信 html作为发送方,通过window.ReactNativeWebView.postMessage发送消息,RN端通过onMessage接收
三、话不多说,直接实操,具体的核心代码如下:
1、react native端的配置
1.1、 webview设置
<WebView scrollEnabled={true} bounces={true} ref={ref => this.web = ref} source={{uri: this.props.url}} mixedContentMode='always' onMessage={({nativeEvent: state}) => { // 用户自定义数据 this.onCustomMessage(state.data); }} //此方法可不添加 injectedJavaScript={`(function() { window.postMessage = function(data) { window.ReactNativeWebView.postMessage(data); }; })()`} javaScriptEnabled={true}//指定WebView中是否启用JavaScript scalesPageToFit={false}// 布尔值,控制网页内容是否自动适配视图的大小,同时启用用户缩放功能。默认为true。 startInLoadingState={true} //强制WebView在第一次加载时先显示loading视图 renderLoading={() => <Spinner isVisible={true}/>} renderError={() => this.loadingErrorView()} onError={(e) => { if (e && deviceInfo.isAndroid){ this.setState({loadLocalErrorView:true}) } }} />
1.2、react native端onMessage消息处理
/*App开放接口给H5调用*/ onCustomMessage(data) { if (data){ //接收H5传的参数 let object = JSON.parse(data); switch (object.methodName) { case webApi.getToken: { //构造要传递H5的参数 let responseData = { methodName: object.methodName, resId: object.reqId, data: {token: AppManager.instance().getToken() || ''}, }; // 调用H5接口,发送消息到H5 this.web && this.web.injectJavaScript(`window.aaa.getToken(${JSON.stringify(responseData)})`); } break; } } };
2、H5端的配置
2.1、H5调用RN端方法
let requestData = {
methodName: 'getToken', // 调用RN传递的方法名称
reqId: new Date().getTime(), // 调用RN获取的时间戳,精确到毫秒
params: {} // 调用RN传递的实际参数
}
//调用RN的getToken方法
window.ReactNativeWebView.postMessage(JSON.stringify(requestData))
2.2、H5暴露方法供RN端调用
window.sigWebApi.getToken = (res) => {
//RN调用H5的getToken方法
this.$store.state.token = JSON.parse(JSON.stringify(res)).data.token
this.$store.state.billCreateIp = JSON.parse(JSON.stringify(res)).ip
}
2.3、sigWebApi为Vue对象
window.sigWebApi.getDeviceInfo中的sigWebApi,是将vue挂在window 对象上,实现能调用组件和方法,也可以直接将方法挂载在window对象上。
window.sigWebApi = new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})