一、vue插件写法
1. utils/jsBridge/Bridge.js //封装了与原生注册通讯的函数
2. utils/jsBridge/BridgeCmd.js //每个Api的名字,与原生开发人员约定好
3. utils/jsBridge/BridgeRegisterHandle.js //封装桥能力的函数,暴露出去
二、Bridge.js文件:实现与原生通讯的代码段,插件的注册,已经将方法挂在到vue原型上,方法集中在此处理。
import { isAndroidModel, isIosModel } from '@/utils/model.js';//该文件用来判断平台环境iOS,Android
const JsBridgePlugin = {
install(Vue, option) {
if (isAndroidModel || isIosModel) {
Vue.prototype.$jsBridge = {
callHandler: function () {},
registerHandler: function () {}
}
}
if (isAndroidModel) {//Android
androidBridge(function (bridge) {
bridge.init(function (message, responseCallback) {
console.log('JS got a message', message)
const data = {
'Javascript Responds': 'Wee!'
}
responseCallback(data)
})
Vue.prototype.$jsBridge = bridge
option.ready()
})
}
if (isIosModel) {//iOS
iosBridge(function (bridge) {
const {
callHandler,
registerHandler
} = bridge
Vue.prototype.$jsBridge = bridge
Object.assign(Vue.prototype.$jsBridge, {
callHandler() {
callHandler(...arguments);
},
registerHandler() {
registerHandler(...arguments)
}
})
option.ready()
})
}
}
}
// Android调用原生的方法封装:
// (前端js与原生Native通信方法外层包裹的固定代码)
function androidBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback]
var WVJBIframe = document.createElement('iframe')
WVJBIframe.style.display = 'none'
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'
document.documentElement.appendChild(WVJBIframe)
let timerRemoveIframe = setTimeout(function () {
document.documentElement.removeChild(WVJBIframe)
clearTimeout(timerRemoveIframe)
timerRemoveIframe = null
}, 0)
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
} else {
document.addEventListener('WebViewJavascriptBridgeReady', function () {
callback(window.WebViewJavascriptBridge)
}, false)
}
}
// iOS调用原生的方法封装:
function iosBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback]
var WVJBIframe = document.createElement('iframe')
WVJBIframe.style.display = 'none'
WVJBIframe.src = 'https://__bridge_loaded__'
document.documentElement.appendChild(WVJBIframe)
let timerRemoveIframe = setTimeout(function () {
document.documentElement.removeChild(WVJBIframe)
clearTimeout(timerRemoveIframe)
timerRemoveIframe = null
}, 0)
}
export default JsBridgePlugin
三、BridgeCmd.js: 调用原生能力的Api名字(与原生约定好)。
// callHandler:H5调用原生能力
export const getAppInfo = 'getAppInfo' // 获取平台信息
export const downloadZip = 'downloadZip'// 下载zip
// registerHandler:原生调用H5
export const downloadZipHandle = 'downloadZipHandle'// 监听下载进度
四、BridgeRegisterHandle.js:原生返回给vue的回调函数的封装。
import Vue from 'vue';
import { downloadZip, getAppInfo, downloadZipHandle } from './BridgeCmd.js';
export const jsBridgeGetAppInfo = ({ params = {}, complete = () => {} } = {}) => {
const jsBridge = Vue.prototype.$jsBridge
const { callHandler } = jsBridge
callHandler( getAppInfo, params, res => complete(res) );
}
export const jsBridgeDownloadZip = ({ params = { url: '' }, complete = () => {} } = {}) => {
const jsBridge = Vue.prototype.$jsBridge
const { callHandler } = jsBridge
callHandler( downloadZip, params, res => complete(res) );
}
export const jsBridgeDownloadZipHandle = ({ complete = () => {} } = {}) => {
const jsBridge = Vue.prototype.$jsBridge
const { registerHandler } = jsBridge
registerHandler( downloadZipHandle, res => complete(res) );
}
五、vue 项目 main.js文件
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 异步懒加载引入Bridge,注意:import函数是异步引入,若是刚打开项目时候,需要马上调用某个桥能力,则需要重新考虑引入时机。
import( /* webpackChunkName:"Bridge" */ '@/utils/jsBridge/Bridge.js').then((module) => {
const Bridge = module.default
Vue.use(Bridge, {
ready() { console.log('桥链接初始化完毕', '<<<--- ') }
});
});
new Vue({
render: h => h(App),
}).$mount('#app')
六、页面调用
<template>
<div>
<h1>vue与原生混合开发--jsBridge</h1>
</div>
</template>
<script>
import { jsBridgeDownloadZip,jsBridgeDownloadZipHandle} from '@/utils/jsBridge/BridgeRegisterHandle.js'
export default {
name: "App",
mounted() {
//H5调用原生方式:::
jsBridgeDownloadZip({
params: {
url: `https://console.warpiot.com/iot-app/appDownload/test_v1/dist.zip?t=${Date.now()}`
},
complete: (res) => { console.log(res, '<<<--- jsBridgeDownloadZip res') }
});
}
//原生调用H5,类似监听,通知给H5说下载进度如何了
jsBridgeDownloadZipHandle({
complete: (res) => {
console.log(res, '<<<--- 下载进度')
const { code } = res //code: 1000 , 1001 , 1002 , 1003 , 1004 , 1005
if (code === 1003) {
console.log('下载结束', '<<<--- ')
window.location.reload()
}
}
});
};
</script>
<style lang="scss" scope>
</style>