refactor(common/lang): add shared component lang pack support
add shared language pack system for cross-page components, normalize component and page lang packs automatically, inject shared packs during language merge
This commit is contained in:
@@ -20,6 +20,95 @@ const _fieldResultCache = {};
|
||||
let _cachedLangPath = '';
|
||||
let _cachedLangPathPage = null;
|
||||
|
||||
// 组件级共享语言包。
|
||||
// 这些语言包不隶属于某个页面,但组件会在任意页面中直接调用
|
||||
// $lang('components.xxx') / $lang('components-diy.xxx')。
|
||||
// 因此必须在每个页面的合并语言包中统一注入,否则运行时会出现 raw key。
|
||||
const SHARED_LANG_PACKS = [
|
||||
'components/img-cropping',
|
||||
'components/mescroll',
|
||||
'components/ns-birthday-gift',
|
||||
'components/ns-form',
|
||||
'components/ns-login',
|
||||
'components/ns-new-gift',
|
||||
'components/ns-newform',
|
||||
'components/ns-payment',
|
||||
'components/ns-select-time',
|
||||
'components/nsChatOrder',
|
||||
'components/nsContact',
|
||||
'components/nsGoodsPromotion',
|
||||
'components/payment',
|
||||
'components/privacy-popup',
|
||||
'components/register-reward',
|
||||
'components/wxwork-contact',
|
||||
'components/yuyue-date',
|
||||
'components-diy/diy-article',
|
||||
'components-diy/diy-bargain',
|
||||
'components-diy/diy-category',
|
||||
'components-diy/diy-category-item',
|
||||
'components-diy/diy-coupon',
|
||||
'components-diy/diy-fenxiao-goods-list',
|
||||
'components-diy/diy-goods-list',
|
||||
'components-diy/diy-index-page',
|
||||
'components-diy/diy-member-info',
|
||||
'components-diy/diy-notice',
|
||||
'components-diy/diy-payment-qrcode',
|
||||
'components-diy/diy-pinfan',
|
||||
'components-diy/diy-pintuan',
|
||||
'components-diy/diy-seckill',
|
||||
'components-diy/diy-store',
|
||||
'components-diy/diy-video',
|
||||
];
|
||||
|
||||
function toCamelCaseName(name) {
|
||||
return String(name || '').replace(/-([a-z])/g, function(_, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
function normalizeSharedLangPack(path, langData) {
|
||||
if (!langData || typeof langData !== 'object') return {};
|
||||
|
||||
const segments = String(path || '').split('/');
|
||||
const group = segments[0];
|
||||
const fileName = segments[segments.length - 1];
|
||||
if (group !== 'components' && group !== 'components-diy') return langData;
|
||||
|
||||
if (langData[group]) return langData;
|
||||
|
||||
const componentName = toCamelCaseName(fileName);
|
||||
const keys = Object.keys(langData);
|
||||
|
||||
if (keys.length === 1 && langData[keys[0]] && typeof langData[keys[0]] === 'object') {
|
||||
return {
|
||||
[group]: langData
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
[group]: {
|
||||
[componentName]: langData
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function normalizePageLangPack(path, langData) {
|
||||
if (!path || !langData || typeof langData !== 'object') return langData || {};
|
||||
|
||||
const segments = String(path).split('/').filter(Boolean);
|
||||
if (!segments.length) return langData;
|
||||
|
||||
let namespaced = {};
|
||||
let cursor = namespaced;
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
const segment = toCamelCaseName(segments[i]);
|
||||
cursor[segment] = i === segments.length - 1 ? deepCloneLang(langData) : {};
|
||||
cursor = cursor[segment];
|
||||
}
|
||||
|
||||
return deepMergeLang(deepCloneLang(langData), namespaced);
|
||||
}
|
||||
|
||||
// 清除所有语言缓存(切语言/切租户/远端覆写更新时调用)
|
||||
function invalidateLangCaches() {
|
||||
for (const k in _mergedLangCache) { if (Object.prototype.hasOwnProperty.call(_mergedLangCache, k)) delete _mergedLangCache[k]; }
|
||||
@@ -715,8 +804,15 @@ export default {
|
||||
if (!mergedLang) {
|
||||
try {
|
||||
const lang = loadLangPackSync(locale, 'common');
|
||||
const currentPageLang = langPath ? loadLangPackSync(locale, langPath) : {};
|
||||
mergedLang = deepMergeLang(deepCloneLang(lang), deepCloneLang(currentPageLang));
|
||||
const currentPageLang = langPath ? normalizePageLangPack(langPath, loadLangPackSync(locale, langPath)) : {};
|
||||
mergedLang = deepCloneLang(lang);
|
||||
for (const sharedPath of SHARED_LANG_PACKS) {
|
||||
const sharedLang = normalizeSharedLangPack(sharedPath, loadLangPackSync(locale, sharedPath));
|
||||
if (sharedLang && typeof sharedLang === 'object') {
|
||||
mergedLang = deepMergeLang(mergedLang, deepCloneLang(sharedLang));
|
||||
}
|
||||
}
|
||||
mergedLang = deepMergeLang(mergedLang, deepCloneLang(currentPageLang));
|
||||
const ovr = overrideCache[getOverrideMemKey(locale)];
|
||||
if (ovr && ovr.map) applyOverrides(mergedLang, ovr.map);
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user