Files
huihuiSquare/digital-avatar-app/src/utils/uniapp-bridge.ts
T

86 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 会会数字分身 H5 ↔ uniapp 原生壳 桥接工具
// 协议详见 uniapp-avatar/README.md
//
// uni-webview bridge is bundled by main.ts; no external CDN is required.
const BRIDGE_HANDLER = '__uniBridgeHandle__'
export interface UniLaunchParams {
token?: string
userId?: string
nickname?: string
avatar?: string
ts?: string
}
const PARAM_KEYS: (keyof UniLaunchParams)[] = ['token', 'userId', 'nickname', 'avatar', 'ts']
function readParams(search: string, target: UniLaunchParams): void {
const sp = new URLSearchParams(search)
for (const key of PARAM_KEYS) {
const value = sp.get(key)
if (value) target[key] = value
}
}
// 是否运行在 uniapp web-view 环境中
export function isInUniWebView(): boolean {
return !!(window as any).uni?.webView
}
// 解析 web-view 加载 URL 时原生注入的参数(token / 会会用户)
export function getLaunchParams(): UniLaunchParams {
const params: UniLaunchParams = {}
readParams(window.location.search, params)
const hashQueryIndex = window.location.hash.indexOf('?')
if (hashQueryIndex >= 0) {
readParams(window.location.hash.slice(hashQueryIndex + 1), params)
}
return params
}
// Remove the one-time login credential before any route is rendered or logged.
export function stripLaunchToken(): void {
const url = new URL(window.location.href)
url.searchParams.delete('token')
const hash = url.hash.slice(1)
const queryIndex = hash.indexOf('?')
if (queryIndex >= 0) {
const path = hash.slice(0, queryIndex)
const hashParams = new URLSearchParams(hash.slice(queryIndex + 1))
hashParams.delete('token')
const query = hashParams.toString()
url.hash = `${path}${query ? `?${query}` : ''}`
}
window.history.replaceState(window.history.state, '', `${url.pathname}${url.search}${url.hash}`)
}
// H5 → 原生:发送事件(需引入 uniapp web-view bridge)
export function postToNative(message: Record<string, any>): boolean {
if (!isInUniWebView()) return false
;(window as any).uni.webView.postMessage({ data: message })
return true
}
// 原生 → H5:注册消息处理(原生通过 web-view.evalJS 调用 window.__uniBridgeHandle__)
export function onNativeMessage(handler: (message: any) => void): void {
;(window as any)[BRIDGE_HANDLER] = (message: any) => {
try {
handler(message)
} catch (e) {
console.error('[uniBridge] handler error', e)
}
}
}
// 便捷事件
export const UniEvents = {
ready: () => postToNative({ type: 'ready' }),
needLogin: () => postToNative({ type: 'needLogin' }),
setTitle: (title: string) => postToNative({ type: 'setTitle', title }),
navigate: (path: string) => postToNative({ type: 'navigate', path }),
back: () => postToNative({ type: 'back' })
}