feat(mp-share): add disabled share page list and hide share menu for specific pages
新增了禁用分享的页面配置列表,针对指定页面主动隐藏转发按钮,同时优化了分享逻辑的兜底和性能。 具体包括: 1. 增加_DISABLED_PAGES集合管理禁分享页面路由 2. 添加页面禁用检查和隐藏分享菜单工具方法 3. 在created和onLoad阶段自动隐藏对应页面的转发按钮 4. 优化onShow和分享钩子的禁用逻辑,避免无效请求和调用
This commit is contained in:
@@ -30,6 +30,68 @@ const _safeGetCurrentPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 关闭分享能力的页面 route 列表(不带前导斜杠,与 mp-weixin page.route 保持一致)
|
||||
*
|
||||
* 为什么需要:
|
||||
* mp-share-default.js 通过 Vue.mixin 全局注入 onShareAppMessage / onShareTimeline,
|
||||
* 但有些页面不适合"分享":
|
||||
* 1) webview 容器页: 转发它等于转发一个 iframe 壳,无意义且会暴露内部 src
|
||||
* 2) 隐私弹窗 / 登录中转页: 状态不稳定,转出去体验差
|
||||
* 3) 任何业务明确要求"不分享"的页面
|
||||
*
|
||||
* 命中后行为:
|
||||
* - mixin 内部不再拉取分享配置(节省一次 HTTP 请求)
|
||||
* - mixin 注入的 onShareAppMessage / onShareTimeline / $mpShare_* 工具方法仍然存在,
|
||||
* 但内部立即调用 wx.hideShareMenu() 把转发按钮从右上角菜单中隐藏
|
||||
* - 这两条防线双保险:即使 mixin 钩子被业务侧转发链路误触发,也不会显示分享弹窗
|
||||
*
|
||||
* 备选方案对比(都没选,原因列在下方):
|
||||
* - 在 created 里 this.onShareAppMessage = undefined:
|
||||
* Vue mixin 合并策略会把 undefined 视为"未声明",mixin 的钩子仍然生效 → 不可靠
|
||||
* - mixin 内 return null / 不 return:
|
||||
* 微信会回退到默认 title 转发,按钮仍显示 → 不可靠
|
||||
* - 使用 wx.hideShareMenu(本方案采用):
|
||||
* 微信官方 API,会立即把"转发"按钮从当前页右上角菜单中隐藏,行为最稳
|
||||
*/
|
||||
const _DISABLED_PAGES = new Set([
|
||||
'pages_tool/webview/webview', // webview 容器,转发无意义
|
||||
]);
|
||||
|
||||
const _isCurrentPageDisabled = () => {
|
||||
const page = _safeGetCurrentPage();
|
||||
if (!page) return false;
|
||||
const route = (page.route || (page.$page && page.$page.path) || '').replace(/^\//, '');
|
||||
return _DISABLED_PAGES.has(route);
|
||||
};
|
||||
|
||||
/**
|
||||
* 主动隐藏当前页的"转发"按钮
|
||||
* - 只能在 mp-weixin 环境调用(其它平台 wx 全局不存在)
|
||||
* - 必须在 onLoad 之后调用(需要 Page 实例已注册完成)
|
||||
* - 失败时静默吞掉(权限/版本/非微信环境都可能导致失败)
|
||||
*/
|
||||
const _hideShareMenu = () => {
|
||||
try {
|
||||
// #ifdef MP-WEIXIN
|
||||
if (typeof wx !== 'undefined' && typeof wx.hideShareMenu === 'function') {
|
||||
wx.hideShareMenu({
|
||||
menus: ['shareAppMessage', 'shareTimeline']
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
} catch (e) {
|
||||
// 静默:旧基础库可能不支持 menus 参数,降级到无参版本
|
||||
try {
|
||||
// #ifdef MP-WEIXIN
|
||||
if (typeof wx !== 'undefined' && typeof wx.hideShareMenu === 'function') {
|
||||
wx.hideShareMenu();
|
||||
}
|
||||
// #endif
|
||||
} catch (e2) { /* ignore */ }
|
||||
}
|
||||
};
|
||||
|
||||
const _getCurrentPath = (withQuery = true) => {
|
||||
const page = _safeGetCurrentPage();
|
||||
if (!page) return '';
|
||||
@@ -90,11 +152,30 @@ export default {
|
||||
__mpShareCache: null, // 当前页面的分享配置
|
||||
};
|
||||
},
|
||||
/**
|
||||
* 在实例创建阶段检查当前页面是否在 _DISABLED_PAGES 列表中。
|
||||
* 命中后调用 wx.hideShareMenu 把当前页的"转发"按钮从右上角菜单中隐藏。
|
||||
*/
|
||||
created() {
|
||||
try {
|
||||
if (_isCurrentPageDisabled()) {
|
||||
// 立即隐藏(此时 wx 还没完全就绪,先尝试一次;失败也无所谓,onLoad 会再调一次)
|
||||
_hideShareMenu();
|
||||
}
|
||||
} catch (e) {}
|
||||
},
|
||||
onLoad() {
|
||||
try {
|
||||
if (_isCurrentPageDisabled()) {
|
||||
// 命中关闭列表的页面:
|
||||
// 1) 再次调 wx.hideShareMenu(此时 Page 已就绪,稳定生效)
|
||||
// 2) 不再拉取分享配置,避免无谓请求
|
||||
_hideShareMenu();
|
||||
return;
|
||||
}
|
||||
const path = _getCurrentPath(true);
|
||||
_getShareConfig(path).then(cfg => {
|
||||
// 后端未返回配置时,注入站点名作为默认标题
|
||||
// 后端未返回配置时,注入站点名作为默认标题
|
||||
if (cfg && !cfg.title) {
|
||||
const siteName = (this.$store && this.$store.state && this.$store.state.siteInfo && this.$store.state.siteInfo.site_name) || '';
|
||||
cfg.title = siteName || '小程序分享';
|
||||
@@ -104,21 +185,27 @@ export default {
|
||||
} catch (e) {}
|
||||
},
|
||||
onShow() {
|
||||
// 兜底:进入页面后如果尚未就绪,再异步拉一次
|
||||
if (!this.__mpShareCache) {
|
||||
try {
|
||||
const path = _getCurrentPath(true);
|
||||
_getShareConfig(path).then(cfg => {
|
||||
this.__mpShareCache = cfg;
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
// 兜底:进入页面后如果尚未就绪,再异步拉一次
|
||||
if (this.__mpShareCache) return;
|
||||
if (_isCurrentPageDisabled()) return; // 命中关闭列表,不再拉
|
||||
try {
|
||||
const path = _getCurrentPath(true);
|
||||
_getShareConfig(path).then(cfg => {
|
||||
this.__mpShareCache = cfg;
|
||||
});
|
||||
} catch (e) {}
|
||||
},
|
||||
/**
|
||||
* 全局默认 onShareAppMessage:
|
||||
* uni-app 规范:组件自身的钩子优先级 > mixin,因此已显式声明的页面不受影响。
|
||||
* 全局默认 onShareAppMessage:
|
||||
* uni-app 规范:组件自身的钩子优先级 > mixin,因此已显式声明的页面不受影响。
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
// 命中禁用列表的页面:即使 wx.hideShareMenu 因某些原因没生效,
|
||||
// 这里直接 return undefined / 也不主动拼 cfg,让微信回退到默认行为
|
||||
// (主防线是 wx.hideShareMenu,这里只是兜底)
|
||||
if (_isCurrentPageDisabled()) {
|
||||
return undefined;
|
||||
}
|
||||
const cfg = this.__mpShareCache;
|
||||
if (cfg && cfg.title) {
|
||||
return {
|
||||
@@ -127,17 +214,20 @@ export default {
|
||||
imageUrl: cfg.imageUrl || ''
|
||||
};
|
||||
}
|
||||
// 后端无配置时:使用站点名 + 当前路径
|
||||
// 后端无配置时:使用站点名 + 当前路径
|
||||
return {
|
||||
title: _buildFallback(_getCurrentPath(true)).title,
|
||||
path: _getCurrentPath(true)
|
||||
};
|
||||
},
|
||||
/**
|
||||
* 全局默认 onShareTimeline(朋友圈):
|
||||
* 朋友圈只支持 query(不能直接传 path),从 cfg.path 中抽取 ? 之后的 query。
|
||||
* 全局默认 onShareTimeline(朋友圈):
|
||||
* 朋友圈只支持 query(不能直接传 path),从 cfg.path 中抽取 ? 之后的 query。
|
||||
*/
|
||||
onShareTimeline() {
|
||||
if (_isCurrentPageDisabled()) {
|
||||
return undefined;
|
||||
}
|
||||
const cfg = this.__mpShareCache;
|
||||
if (cfg && cfg.title) {
|
||||
const path = cfg.path || _getCurrentPath(true);
|
||||
|
||||
Reference in New Issue
Block a user