Vue框架下 JS与native的交互(iOS&Android)

匿名 (未验证) 提交于 2019-12-03 00:41:02

需求: 在原生App里打开webview, 嵌入H5. 在H5中点击某个元素, 触发与native app交互, 又跳回到app中. 同理, 在app中完成某项操作后, 获得某个参数, 根据这个状态刷新页面.

框架: Vue. JavaScript原生的写法已经调通了, 并且与native端的已经联调通过. 所以这里是把它们迁移到Vue框架的写法.

这里要区分iOS系统和Android系统.

iOSϵͳ

  1. 在这里与iOS开发的同事协商后, 决定使用 WebViewJavascriptBridge来开发. 前端不需要放入任何js插件. 只需要准备一下这段内容.

bridge.js

function setupWebViewJavascriptBridge(callback) {   if (window.WebViewJavascriptBridge) {     return callback(window.WebViewJavascriptBridge)   }   if (window.WVJBCallbacks) {     returnwindow.WVJBCallbacks.push(callback)   }   window.WVJBCallbacks = [callback]   let WVJBIframe = document.createElement(‘iframe‘)   WVJBIframe.style.display = ‘none‘   WVJBIframe.src = ‘https://__bridge_loaded__‘   document.documentElement.appendChild(WVJBIframe)   setTimeout(() => {     document.documentElement.removeChild(WVJBIframe)   }, 0) }  export default {   callhandlerIOS(name, data, callback) {       setupWebViewJavascriptBridge(function (bridge) {         bridge.callHandler(name, data, callback)       })     },   registerhandlerIOS(name, callback) {       setupWebViewJavascriptBridge(function (bridge) {         bridge.registerHandler(name, function (data, responseCallback) {           callback(data, responseCallback)         })       })     } } 
  1. 在main.js里注入
import Bridge from "./js/bridge.js";  Vue.prototype.$bridge = Bridge  //在这里注入后, 页面里所有需要用到调用native的地方, 都可以直接调用this.$bridge.xxx  new Vue({   el: "#app",   router,   store,  // Bridge,     components: { App },   template: "<App/>", }) 
  1. 在要使用的.vue文件里使用

这里举一个例子.

callNative方法里使用this.$bridge.callhandler(‘ObjC Echo‘, params, function(response){//todo})

其中ObjC Echo是和客户端约定好的方法. 即在客户端注册好的方法, 写上这个方法名, 在使用的时候客户端就能接收到, 从而拿到params里的参数, 而后面跟的function(response){}就是处理response里的数据. 进行一些操作.

this.$bridge.callhandlerIOS(     "HY_H5_CALL_NATIVE",     { action: "pick me" },     data => {         // 处理返回数据     } )

使用this.$bridge.registerhandler(‘JS Echo‘, (data, responseCallback)=>{//todo}

JS Echo即是和客户端约定好的方法名, 在客户端使用这个方法名时, 会自动调起H5执行某些操作. 客户端传来的信息放在data里, responseCallback即执行回调.

this.$bridge.registerhandlerIOS("JS Echo", (data, responseCallback) => {     alert("JS Echo called with:", data);     // this.responseCallback(data) }); 

Androidϵͳ

由于Android系统同样也使用webviewJavaScriptBridge, 所以我自然而然想到了是否也能像iOS一样export出两个处理的handler.

  1. 在bridge.js中添加声明代码
//Android 交互声明 function connectWebViewJavascriptBridgeANDROID(callback) {   if (window.WebViewJavascriptBridge) {     callback(WebViewJavascriptBridge);   } else {     document.addEventListener(       "WebViewJavascriptBridgeReady",       function () {         callback(WebViewJavascriptBridge);       },       false     );   } }  
  1. 在bridge.js的export中添加导出

这里我在handler后面添加了Android作为和iOS的handler做区分.

   callhandlerAndroid(name, data, callback){  //Android方法     connectWebViewJavascriptBridgeANDROID(function(bridge){       bridge.callHandler(name, data, callback)     })   },   registerhandlerAndroid(name, callback){  //Android方法     connectWebViewJavascriptBridgeANDROID(function(bridge){       bridge.init(function(message, responseCallback) {         if (responseCallback) {           // responseCallback(data);         }       });       bridge.registerHandler(name, function(data, responseCallback){         callback(data, responseCallback)       })     })   } 
  1. .vue文件中使用. 使用方法同iOS
this.$bridge.callhandlerAndroid(     ‘action‘,      {message: ‘111‘},     function(response){} ) 
this.$bridge.registerhandlerAndroid(     "registerAction",     (message, responseCallback) => {         alert("JS Echo called with:" + message);         // this.responseCallback(data)     } );

至此, js和Android, iOS端就算调通了.

感觉Android这一块还有很多可以优化的地方, 但是我的js还掌握的不是很牢靠...所以就先这样吧. 等以后我又新的感悟了, 再来更新.

附上所有代码

  1. bridge.js代码
//iOS 交互声明 function connectWebViewJavascriptBridgeIOS(callback) {   if (window.WebViewJavascriptBridge) {     return callback(window.WebViewJavascriptBridge)   }   if (window.WVJBCallbacks) {     returnwindow.WVJBCallbacks.push(callback)   }   window.WVJBCallbacks = [callback]   let WVJBIframe = document.createElement(‘iframe‘)   WVJBIframe.style.display = ‘none‘   WVJBIframe.src = ‘https://__bridge_loaded__‘   document.documentElement.appendChild(WVJBIframe)   setTimeout(() => {     document.documentElement.removeChild(WVJBIframe)   }, 0) }   //Android 交互声明 function connectWebViewJavascriptBridgeANDROID(callback) {   if (window.WebViewJavascriptBridge) {     callback(WebViewJavascriptBridge);   } else {     document.addEventListener(       "WebViewJavascriptBridgeReady",       function () {         callback(WebViewJavascriptBridge);       },       false     );   } }  export default {   callhandlerIOS(name, data, callback) { //iOS的方法     connectWebViewJavascriptBridgeIOS(function (bridge) {       bridge.callHandler(name, data, callback)     })   },   registerhandlerIOS(name, callback) { //iOS的方法     connectWebViewJavascriptBridgeIOS(function (bridge) {       bridge.registerHandler(name, function (data, responseCallback) {         callback(data, responseCallback)       })     })   },   callhandlerAndroid(name, data, callback){  //Android方法     connectWebViewJavascriptBridgeANDROID(function(bridge){       bridge.callHandler(name, data, callback)     })   },   registerhandlerAndroid(name, callback){  //Android方法     connectWebViewJavascriptBridgeANDROID(function(bridge){       bridge.init(function(message, responseCallback) {         if (responseCallback) {           // responseCallback(data);         }       });       bridge.registerHandler(name, function(data, responseCallback){         callback(data, responseCallback)       })     })   } } 
  1. main.js代码
import Bridge from "./js/bridge.js";  Vue.prototype.$bridge = Bridge   /* eslint-disable no-new */ new Vue({   el: "#app",   router,   store,   components: { App },   template: "<App/>", });  
  1. .vue文件
<template>     <div>         <h1>hi, this is a test</h1>         <h2 v-if="isShow">234</h2>               <button @click="callNative">点击点击</button>         <h3>234</h3>     </div> </template>  <script> export default {     data() {         return {             isShow: false         };     },     created() {         this.$bridge.registerhandlerIOS("JS Echo", (data, responseCallback) => {             alert("JS Echo called with:", data);             // this.responseCallback(data)         });         this.$bridge.registerhandlerAndroid(             "registerAction",             (message, responseCallback) => {                 alert("JS Echo called with:" + message);                 // this.responseCallback(data)             }         );     },     methods: {         callNative() {             this.isShow = !this.isShow;             if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {                 this.$bridge.callhandlerIOS(                     "HY_H5_CALL_NATIVE",                     { action: "pick me" },                     data => {                         // 处理返回数据                     }                 )             }else if (/(Android)/i.test(navigator.userAgent)){                 this.$bridge.callhandlerAndroid(                     ‘action‘,                      {message: ‘111‘},                     function(response){}                 )             }         },      } }; </script>  <style> button {     margin: 30px auto;     display: block;     padding: 10px;     border: 1px solid #ccc;     background-color:dodgerblue } </style>  

原文:https://www.cnblogs.com/darthbadwolf/p/9336651.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!