diff --git a/common/js/quickapp-pull-refresh.js b/common/js/quickapp-pull-refresh.js new file mode 100644 index 0000000..7ef05d6 --- /dev/null +++ b/common/js/quickapp-pull-refresh.js @@ -0,0 +1,33 @@ +/** + * 快应用宿主环境下的下拉刷新 → 原生 webview.reload() 转发 mixin + * + * 在已启用 enablePullDownRefresh 的 uniapp 页面 mixin 链中加入本文件, + * 当用户在原生快应用 webview 内下拉刷新时,会通过 this.$util.requestQuickAppReload() + * 把指令发回快应用 shell(对应 hello.ux onMessage 中的 'reload' 处理); + * 其余平台走默认的 uni.stopPullDownRefresh 即可。 + * + * 用法: + * import pullReload from '@/common/js/mixins/quickapp-pull-refresh.js'; + * export default { mixins: [..., pullReload] } + * + * 注意: + * - 请确保对应的 pages.json style 块中开启 "enablePullDownRefresh": true + * - 不要在本文件里覆盖 onPullDownRefresh,否则会被本页/上游 mixin 拦截失效 + */ +export default { + onPullDownRefresh() { + try { + if (this.$util && typeof this.$util.requestQuickAppReload === 'function' + && this.$util.requestQuickAppReload()) { + // 原生侧 webview.reload() 会把整个 H5 页面替换掉,这里只是兜底停动画 + setTimeout(() => { + try { uni.stopPullDownRefresh(); } catch (_) { /* swallow */ } + }, 800); + return; + } + } catch (e) { + console.error('[quickapp-pull-refresh] crashed:', e); + } + try { uni.stopPullDownRefresh(); } catch (_) { /* swallow */ } + } +} diff --git a/common/js/util.js b/common/js/util.js index 7f79763..05caeb7 100644 --- a/common/js/util.js +++ b/common/js/util.js @@ -1782,6 +1782,63 @@ export default { return true; }, + // #ifdef H5 + /** + * H5 → 原生(快应用 webview)通信:发送一条结构化 postMessage 给宿主 + * 与 stub-app-projects/mp-quickapp 中 onMessage 收信协议一一对应: + * 原生识别 payload.type(payload.action / payload.cmd 兼容)值: + * 'reload' / 'pullRefresh' / 'refresh' → 触发 webview.reload() + * @param {string} cmd 指令名,如 'reload' / 'share' / 'close' + * @param {Object} [extra] 附加字段,会合并进消息体(不可覆盖 type/source/t) + * @returns {boolean} 是否成功投递(非快应用环境会直接返回 false,但不抛错) + */ + notifyNativeHost(cmd, extra) { + try { + if (!cmd || typeof cmd !== 'string') return false; + if (!this.isQuickApp()) return false; + var reserved = { type: cmd, source: 'h5', t: Date.now() }; + var data = reserved; + if (extra && typeof extra === 'object') { + for (var k in extra) { + if (Object.prototype.hasOwnProperty.call(extra, k) && !(k in reserved)) { + data[k] = extra[k]; + } + } + } + var payload = JSON.stringify(data); + // 主通道:window.parent.postMessage + try { + if (window.parent && window.parent !== window && typeof window.parent.postMessage === 'function') { + window.parent.postMessage(payload, '*'); + } + } catch (parentErr) { + console.error('[notifyNativeHost] parent postMessage failed:', parentErr); + } + // 兜底通道:在同窗口内派发 message 事件,部分宿主通过该路径收信 + try { + window.dispatchEvent(new MessageEvent('message', { data: payload })); + } catch (evtErr) { + console.error('[notifyNativeHost] dispatchEvent failed:', evtErr); + } + return true; + } catch (e) { + console.error('[notifyNativeHost] crashed:', e); + return false; + } + }, + // #endif + + // #ifdef H5 + /** + * 通知快应用宿主重新加载当前 webview(对应下拉刷新等场景) + * 对应原生侧 hello.ux 的 onMessage 处理 'reload' 指令 + * @returns {boolean} + */ + requestQuickAppReload() { + return this.notifyNativeHost('reload', { source: 'pullRefresh' }); + }, + // #endif + /** * 蛇形命名转驼峰命名 * @param {string} str 蛇形命名字符串 diff --git a/main.js b/main.js index 6b0fab1..58a9909 100644 --- a/main.js +++ b/main.js @@ -58,6 +58,14 @@ Vue.prototype.$eventBus = EventBus; Vue.mixin(globalConfig); +// #ifdef H5 +// 全局接管下拉刷新:原生快应用宿主内通过 notifyNativeHost('reload') 转发, +// 其余平台只走 uni.stopPullDownRefresh 兜底,不会影响各页面原 onPullDownRefresh 的其他逻辑 +// 全局 mixin:下拉刷新 → 在快应用宿主内转发原生 webview.reload() +import quickappPullReload from './common/js/quickapp-pull-refresh.js' +Vue.mixin(quickappPullReload); +// #endif + // #ifdef MP-WEIXIN // 全局兜底分享 mixin: // 为所有未显式声明 onShareAppMessage / onShareTimeline 的页面提供默认实现,