内嵌的 html 页面需要和 RN 底层进行通讯,主要用到 react-native-webview 的 window.ReactNativeWebView.postMessage、onMessage、injectJavaScript和html 中的 event 事件机制。
html 传值给 RN
VUE传值
<template>
<button @click="handleClick">test1</button>
</template>
<script>
export default {
name: 'App',
methods:{
handleClick(){
window.ReactNativeWebView.postMessage('hello')
}
}
}
</script>
RN接收
const App = ()=>{
function handleMessage(e){
Alert.alert('提醒',e.nativeEvent.data)
}
return(
<WebView
onMessage={handleMessage}
/>
)
}
RN传值给 html
传值的数据格式设置
-
html=>RN
{ typeCode:'xxx', // 要调用的接口 eventId: 'xxx-uuid',// 事件 id,唯一性,完成原生接口后回传数据 option: {}//接口配置 data: {} // 接口数据 } -
RN=>html
{ code:'',// 执行结果的 code,成功或者失败 error_msg: '',// 错误信息 data: {}// 执行结果 }
具体代码
-
VUE 传值
<template> <button @click="handleClick('camera')">test1</button> </template> <script> export default { name: 'App', methods:{ handleClick(typeCode){ this.postMessage(typeCode) }, getOption(typeCode,options,data){ // 生成唯一事件 id 并返回组合好的配置 const eventId = type+'-'+randomValue() return { typeCode, eventId, options, data } } postMessage(typeCode,options={},data={}){ const config = getOption(typeCode,options,data) return new Promise((resolve,reject)=>{ window.addEventListener(config.eventId,(e)=>{// 注册事件到 window 上面 const response = e.detail if(response.code === 'success'){ resolve(response) return } reject(new Error(response.error_message)) },{ once: true // 设置只允许触发一次,完成后自动移除 }) window.ReactNativeWebView.postMessage(JSON.stringify(config)) }) } } } </script> -
RN传值
const App = ()=>{ let view; function handleMessage(e){ const config = JSON.preas(e.nativeEvent.data) handleOpenCamera(config) } function handleOpenCamera(config) { const data = await openCamra() sendMsgtToHtml(config.eventId,data) } // 注入 js 代码,触发注册好的事件 function sendMsgtToHtml(eventId,info){ const jsCode = ` window.dispatchEvent(new CustomEvent('${eventId}',{'detail':{data:${JSON.stringify( info, )},code:'success'}})) true; // 最后的这个 true 必须设置 ` view.injectJavaScript(jsCode) // 通过注入代码的方式触发事件,回传数据 } return( <WebView ref={(ref)=>view=ref} onMessage={handleMessage} /> ) }
小结
到这基本就完成了互相通讯的设计了,具体的一些细节还需要去补充,例如持续获取数据(监听移动轨迹),拍照获取照片和视频资源等;