Vue架構下 JS與native的互動(iOS&Android)

來源:互聯網
上載者:User

標籤:efault   pad   地方   import   ssh   play   UNC   開發   更新   

需求: 在原生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.xxxnew Vue({  el: "#app",  router,  store, // Bridge,    components: { App },  template: "<App/>",})
  1. 在要使用的.vue檔案裡使用

這裡舉一個例子.

H5調用iOS

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 => {        // 處理返回資料    })
iOS調用H5

使用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
JS調用Android
this.$bridge.callhandlerAndroid(    ‘action‘,     {message: ‘111‘},    function(response){})
Android調用JS
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>

Vue架構下 JS與native的互動(iOS&Android)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.