Vue框架下 JS与native的交互(iOS&Android)
Posted DarthBadwolf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue框架下 JS与native的交互(iOS&Android)相关的知识,希望对你有一定的参考价值。
需求: 在原生App里打开webview, 嵌入H5. 在H5中点击某个元素, 触发与native app交互, 又跳回到app中. 同理, 在app中完成某项操作后, 获得某个参数, 根据这个状态刷新页面.
框架: Vue. javascript原生的写法已经调通了, 并且与native端的已经联调通过. 所以这里是把它们迁移到Vue框架的写法.
iOS系统
- 在这里与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)
})
})
}
}
- 在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/>",
})
- 在要使用的
.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.
- 在bridge.js中添加声明代码
//Android 交互声明
function connectWebViewJavascriptBridgeANDROID(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge);
} else {
document.addEventListener(
"WebViewJavascriptBridgeReady",
function () {
callback(WebViewJavascriptBridge);
},
false
);
}
}
- 在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)
})
})
}
- 在
.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还掌握的不是很牢靠...所以就先这样吧. 等以后我又新的感悟了, 再来更新.
附上所有代码
- 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)
})
})
}
}
- 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/>",
});
.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)的主要内容,如果未能解决你的问题,请参考以下文章