├── README.md ├── device.js └── jsBridge-plugin.js /README.md: -------------------------------------------------------------------------------- 1 | # vue-jsBridge 2 | vue项目中使用jsBridge技术 和原生APP通信 3 | 4 | android [jsBridge库](https://github.com/lzyzsd/JsBridge) 5 | ios [jsBridge库](https://github.com/marcuswestin/WebViewJavascriptBridge) 6 | 7 | ###在vue中使用插件 8 | ``` 9 | import Vue from 'vue' 10 | import JsBridge from 'jsBridge-plugin' 11 | 12 | Vue.use(JsBridge); 13 | ``` 14 | 15 | ###在vue中使用 16 | ``` 17 | import {setJsBridge} from 'jsBridge-plugin' //引入插件 18 | 19 | //vue生命周期钩子 20 | ready : function(){ 21 | 22 | //注册js方法 让原生调用 23 | setJsBridge((bridge)=>{ 24 | 25 | bridge.registerHandler(this.$jsBridgeCmd.publish, (data, responseCallback)=>{ 26 | $("#app_resp").html("点击了提交按钮"); 27 | this.publish().then((id)=>{ 28 | responseCallback(id); 29 | }) 30 | }); 31 | 32 | }); 33 | } 34 | 35 | methods: { 36 | //点击事件方法或者其他场景 37 | addImage(){ 38 | //调用原生方法 需要原生那边也注册方法 39 | this.$jsBridge.callHandler( 40 | this.$jsBridgeCmd.chooseImage 41 | , { name : '添加图片' } 42 | , (responseData) =>{ 43 | //回调函数 44 | } 45 | ); 46 | }, 47 | } 48 | 49 | 50 | ``` 51 | -------------------------------------------------------------------------------- /device.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var device = {}; 3 | var ua = navigator.userAgent; 4 | 5 | var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); 6 | var ipad = ua.match(/(iPad).*OS\s([\d_]+)/); 7 | var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); 8 | var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/); 9 | 10 | device.ios = device.android = device.iphone = device.ipad = device.androidChrome = false; 11 | 12 | // Android 13 | if (android) { 14 | device.os = 'android'; 15 | device.osVersion = android[2]; 16 | device.android = true; 17 | device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0; 18 | } 19 | if (ipad || iphone || ipod) { 20 | device.os = 'ios'; 21 | device.ios = true; 22 | } 23 | // iOS 24 | if (iphone && !ipod) { 25 | device.osVersion = iphone[2].replace(/_/g, '.'); 26 | device.iphone = true; 27 | } 28 | if (ipad) { 29 | device.osVersion = ipad[2].replace(/_/g, '.'); 30 | device.ipad = true; 31 | } 32 | if (ipod) { 33 | device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null; 34 | device.iphone = true; 35 | } 36 | // iOS 8+ changed UA 37 | if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) { 38 | if (device.osVersion.split('.')[0] === '10') { 39 | device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0]; 40 | } 41 | } 42 | 43 | // Webview 44 | device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i); 45 | 46 | 47 | // OS classes 48 | if (device.os) { 49 | classNames.push(device.os, device.os + '-' + device.osVersion.split('.')[0], device.os + '-' + device.osVersion.replace(/\./g, '-')); 50 | if (device.os === 'ios') { 51 | var major = parseInt(device.osVersion.split('.')[0], 10); 52 | for (var i = major - 1; i >= 6; i--) { 53 | classNames.push('ios-gt-' + i); 54 | } 55 | } 56 | 57 | } 58 | 59 | // keng.. 60 | device.isWeixin = /MicroMessenger/i.test(ua); 61 | 62 | export default device; 63 | -------------------------------------------------------------------------------- /jsBridge-plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | import device from './device' 3 | 4 | var JsBridgePlugin = {}; 5 | 6 | JsBridgePlugin.install = function (Vue, option) { 7 | 8 | //初始化jsBridge 9 | Vue.prototype.$jsBridge = { 10 | registerHandler : function (name,callback) { 11 | console.error('没有注册成功') 12 | }, 13 | callHandler : function (name, params, callback) { 14 | console.error('没有调用成功') 15 | } 16 | } 17 | //所有原生和js通信的命令 18 | Vue.prototype.$jsBridgeCmd = { 19 | chooseImage : 'chooseImage', 20 | } 21 | 22 | //先注释掉 初始化jsBridge 需要用到时再初始化 23 | if(device.webView){ 24 | if(device.android){ 25 | androidSetWebViewJavascriptBridge(function(bridge) { 26 | 27 | Vue.prototype.$jsBridge = bridge; 28 | 29 | console.log('初始化$jsBridge'+ (typeof bridge.registerHandler == 'function')) 30 | 31 | }) 32 | }else if(device.ios){ 33 | iosSetupWebViewJavascriptBridge(function(bridge) { 34 | Vue.prototype.$jsBridge = bridge 35 | 36 | // console.log('初始化$jsBridge',Vue.prototype.$jsBridge) 37 | }) 38 | } 39 | } 40 | 41 | }; 42 | export default JsBridgePlugin; 43 | 44 | //安卓 45 | export function androidSetWebViewJavascriptBridge(callback) { 46 | if (window.WebViewJavascriptBridge) { 47 | console.log('有WebViewJavascriptBridge对象') 48 | return callback(WebViewJavascriptBridge) 49 | } else { 50 | console.log('没有WebViewJavascriptBridge对象,等待WebViewJavascriptBridgeReady事件回调') 51 | document.addEventListener( 52 | 'WebViewJavascriptBridgeReady' 53 | , function(){ 54 | console.log('WebViewJavascriptBridgeReady事件回调了') 55 | callback(WebViewJavascriptBridge) 56 | }, 57 | false 58 | ); 59 | } 60 | } 61 | 62 | //ios 63 | export function iosSetupWebViewJavascriptBridge(callback) { 64 | if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } 65 | if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } 66 | window.WVJBCallbacks = [callback]; 67 | var WVJBIframe = document.createElement('iframe'); 68 | WVJBIframe.style.display = 'none'; 69 | WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; 70 | document.documentElement.appendChild(WVJBIframe); 71 | setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) 72 | } 73 | 74 | let func = function () { 75 | 76 | }; 77 | if(device.webView) { 78 | if (device.android) { 79 | func = androidSetWebViewJavascriptBridge 80 | } else if (device.ios) { 81 | func = iosSetupWebViewJavascriptBridge 82 | } 83 | } 84 | 85 | //在路由中使用这个方法 注册web方法让原生调用 86 | export let setJsBridge = func; 87 | --------------------------------------------------------------------------------