Vue 和 原生(webview)交互 解析
效果项目地址UIWebView与JS的深度交互事情的起因还是因为项目需求驱动。折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾。参考 Github上看到了WebViewJavascriptBridge 这个用于UIWebView/WebViews和JS交互的封装库。一开始,我
效果
项目地址
UIWebView与JS的深度交互
事情的起因还是因为项目需求驱动。折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾。
参考 Github上看到了WebViewJavascriptBridge 这个用于UIWebView/WebViews和JS交互的封装库。
- 一开始,我们在Native端和JS端都分别进行初始化:
- OC端:
@property WebViewJavascriptBridge* bridge;
对应的初始化代码如下,在初始化中直接包含了一个用于接收JS的回调:
_bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"ObjC received message from JS: %@", data);
responseCallback(@"Response for message from ObjC");
}];
- JS端:(以下是固定写法,你自己的JS文件中必须包含如下代码)
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener('WebViewJavascriptBridgeReady', function() {
callback(WebViewJavascriptBridge)
}, false)
}
}
connectWebViewJavascriptBridge(function(bridge) {
bridge.init(function(message, responseCallback) {
log('JS got a message', message)
var data = { 'Javascript Responds':'Wee!' }
log('JS responding with', data)
responseCallback(data)
})
}
- 同理,第二条,在JS中调用了bridge.callHandler(‘testJavascriptHandler’),它将触发OC端注册的同名方法:
以上表中的对应关系的解读是,例如第一条:在JS中如果调用了bridge.send(),那么将触发OC端_bridge初始化方法中的回调。
同理,第二条,在JS中调用了bridge.callHandler(‘testJavascriptHandler’),它将触发OC端注册的同名方法:
bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
log('ObjC called testJavascriptHandler with', data)
var responseData = { 'Javascript Says':'Right back atcha!' }
log('JS responding with', responseData)
responseCallback(responseData)
})
了解了使用规则,下面来看看在我们这个实际需求中应用的整体思路:
基于以上的思路,使用vue实现 和 webview的交互
原生调用vue中的方法
由于vue中作用域的关系,所以交互的事件必须挂载到window上,那么实现思路就是写一个vue的plugin(插件),并且把这个插件对象挂载到window上,代码如下:
var hybrid = { install (Vue, options) { // 把当前的对象挂载到vue的全局 Vue.prototype.$hybrid = this; } } // 把vue中绑定的对象挂载到window上 window.Hybrid = hybrid; // 导出共给vue组件中引入使用 export default hybrid
android 中执行调用:
webView.loadUrl("javascript:Hybrid.registerHandler('android', 'jsActivityShare')");
ios 中执行:
// 方法一. JSValue *function = [self.context objectForKeyedSubscript:@"factorial"]; // 方法二. JSValue * function = self.context[@"factorial"]; JSValue *result = [function callWithArguments:@[inputNumber]]; self.showLable.text = [NSString stringWithFormat:@"%@", [result toNumber]];
vue中的方法调原生
需求:实现一个处理原生的数据 然后回掉原生方法, 代码如下:
// 注册原生发过来的方法,name需要注册的方法的名字 registerHandler (name, callBack) { console.log(name + "js 处理原生发送的数据"); try { // eval(this.native.callBack) 必须指定清楚那个对象的函数名字 if (typeof(eval(this.native.callBack)) == "function") { eval("this.native." + callBack + "('js处理完成之后的结果回传给原生客户端');"); } else { // 函数不存在, 抛出异常提示函数不存在 alert(callBack); } }catch(err){ alert(err) // 可执行 } }
原生调用vue组件中的函数
需要使用vue的广播事件,在vue的全局挂载一个事件对象,然后由这个事件对象统一处理事件,代码如下:
Vue.prototype.$eventHub= Vue.prototype.$eventHub || new Vue({data:{'message':''}, template:'<div> {{message}} </ div>'}); this.$eventHub = Vue.prototype.$eventHub;
然后发送广播事件
//调用$emit 方法, 来发送全局的函数 this.$eventHub.$emit('event', yourData);
最后在组件中接受广播事件
// 监听app中发出的事件 this.$eventHub.$on('event', (index)=>{ TODO:: // 调用组件内容函数处理 });
参考:
1. IOS中 使用JavaScriptCore 实现OC与JS的交互
2. UIWebView与JS的深度交互
3. 10分钟教你快速开发一个vue插件并发布npm
更多推荐
所有评论(0)