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 _getCurrentPath = (withQuery = true) => {
|
||||||
const page = _safeGetCurrentPage();
|
const page = _safeGetCurrentPage();
|
||||||
if (!page) return '';
|
if (!page) return '';
|
||||||
@@ -90,11 +152,30 @@ export default {
|
|||||||
__mpShareCache: null, // 当前页面的分享配置
|
__mpShareCache: null, // 当前页面的分享配置
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 在实例创建阶段检查当前页面是否在 _DISABLED_PAGES 列表中。
|
||||||
|
* 命中后调用 wx.hideShareMenu 把当前页的"转发"按钮从右上角菜单中隐藏。
|
||||||
|
*/
|
||||||
|
created() {
|
||||||
|
try {
|
||||||
|
if (_isCurrentPageDisabled()) {
|
||||||
|
// 立即隐藏(此时 wx 还没完全就绪,先尝试一次;失败也无所谓,onLoad 会再调一次)
|
||||||
|
_hideShareMenu();
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
try {
|
try {
|
||||||
|
if (_isCurrentPageDisabled()) {
|
||||||
|
// 命中关闭列表的页面:
|
||||||
|
// 1) 再次调 wx.hideShareMenu(此时 Page 已就绪,稳定生效)
|
||||||
|
// 2) 不再拉取分享配置,避免无谓请求
|
||||||
|
_hideShareMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const path = _getCurrentPath(true);
|
const path = _getCurrentPath(true);
|
||||||
_getShareConfig(path).then(cfg => {
|
_getShareConfig(path).then(cfg => {
|
||||||
// 后端未返回配置时,注入站点名作为默认标题
|
// 后端未返回配置时,注入站点名作为默认标题
|
||||||
if (cfg && !cfg.title) {
|
if (cfg && !cfg.title) {
|
||||||
const siteName = (this.$store && this.$store.state && this.$store.state.siteInfo && this.$store.state.siteInfo.site_name) || '';
|
const siteName = (this.$store && this.$store.state && this.$store.state.siteInfo && this.$store.state.siteInfo.site_name) || '';
|
||||||
cfg.title = siteName || '小程序分享';
|
cfg.title = siteName || '小程序分享';
|
||||||
@@ -104,21 +185,27 @@ export default {
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
// 兜底:进入页面后如果尚未就绪,再异步拉一次
|
// 兜底:进入页面后如果尚未就绪,再异步拉一次
|
||||||
if (!this.__mpShareCache) {
|
if (this.__mpShareCache) return;
|
||||||
try {
|
if (_isCurrentPageDisabled()) return; // 命中关闭列表,不再拉
|
||||||
const path = _getCurrentPath(true);
|
try {
|
||||||
_getShareConfig(path).then(cfg => {
|
const path = _getCurrentPath(true);
|
||||||
this.__mpShareCache = cfg;
|
_getShareConfig(path).then(cfg => {
|
||||||
});
|
this.__mpShareCache = cfg;
|
||||||
} catch (e) {}
|
});
|
||||||
}
|
} catch (e) {}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 全局默认 onShareAppMessage:
|
* 全局默认 onShareAppMessage:
|
||||||
* uni-app 规范:组件自身的钩子优先级 > mixin,因此已显式声明的页面不受影响。
|
* uni-app 规范:组件自身的钩子优先级 > mixin,因此已显式声明的页面不受影响。
|
||||||
*/
|
*/
|
||||||
onShareAppMessage() {
|
onShareAppMessage() {
|
||||||
|
// 命中禁用列表的页面:即使 wx.hideShareMenu 因某些原因没生效,
|
||||||
|
// 这里直接 return undefined / 也不主动拼 cfg,让微信回退到默认行为
|
||||||
|
// (主防线是 wx.hideShareMenu,这里只是兜底)
|
||||||
|
if (_isCurrentPageDisabled()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
const cfg = this.__mpShareCache;
|
const cfg = this.__mpShareCache;
|
||||||
if (cfg && cfg.title) {
|
if (cfg && cfg.title) {
|
||||||
return {
|
return {
|
||||||
@@ -127,17 +214,20 @@ export default {
|
|||||||
imageUrl: cfg.imageUrl || ''
|
imageUrl: cfg.imageUrl || ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// 后端无配置时:使用站点名 + 当前路径
|
// 后端无配置时:使用站点名 + 当前路径
|
||||||
return {
|
return {
|
||||||
title: _buildFallback(_getCurrentPath(true)).title,
|
title: _buildFallback(_getCurrentPath(true)).title,
|
||||||
path: _getCurrentPath(true)
|
path: _getCurrentPath(true)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 全局默认 onShareTimeline(朋友圈):
|
* 全局默认 onShareTimeline(朋友圈):
|
||||||
* 朋友圈只支持 query(不能直接传 path),从 cfg.path 中抽取 ? 之后的 query。
|
* 朋友圈只支持 query(不能直接传 path),从 cfg.path 中抽取 ? 之后的 query。
|
||||||
*/
|
*/
|
||||||
onShareTimeline() {
|
onShareTimeline() {
|
||||||
|
if (_isCurrentPageDisabled()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
const cfg = this.__mpShareCache;
|
const cfg = this.__mpShareCache;
|
||||||
if (cfg && cfg.title) {
|
if (cfg && cfg.title) {
|
||||||
const path = cfg.path || _getCurrentPath(true);
|
const path = cfg.path || _getCurrentPath(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user