mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-02-02 18:28:40 +08:00
feat: Support dayjs and component library in multiple languages
This commit is contained in:
parent
ca1cad0cd3
commit
1d70d71537
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -171,7 +171,10 @@
|
|||||||
"packages/@vben-core/shared/design-tokens/src/**/*.css"
|
"packages/@vben-core/shared/design-tokens/src/**/*.css"
|
||||||
],
|
],
|
||||||
|
|
||||||
"i18n-ally.localesPaths": ["packages/locales/src/langs"],
|
"i18n-ally.localesPaths": [
|
||||||
|
"packages/locales/src/langs",
|
||||||
|
"packages/@core/shared/i18n/src/langs"
|
||||||
|
],
|
||||||
"i18n-ally.enabledParsers": ["json", "ts", "js", "yaml"],
|
"i18n-ally.enabledParsers": ["json", "ts", "js", "yaml"],
|
||||||
"i18n-ally.sourceLanguage": "en",
|
"i18n-ally.sourceLanguage": "en",
|
||||||
"i18n-ally.displayLanguage": "zh-CN",
|
"i18n-ally.displayLanguage": "zh-CN",
|
||||||
|
@ -5,15 +5,11 @@ import { GlobalProvider } from '@vben/widgets';
|
|||||||
import { preferences, usePreferences } from '@vben-core/preferences';
|
import { preferences, usePreferences } from '@vben-core/preferences';
|
||||||
|
|
||||||
import { App, ConfigProvider, theme } from 'ant-design-vue';
|
import { App, ConfigProvider, theme } from 'ant-design-vue';
|
||||||
import zhCN from 'ant-design-vue/es/locale/zh_CN';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
|
|
||||||
import 'dayjs/locale/zh-cn';
|
import { antdLocale } from '#/forward';
|
||||||
|
|
||||||
defineOptions({ name: 'App' });
|
defineOptions({ name: 'App' });
|
||||||
|
|
||||||
dayjs.locale(zhCN.locale);
|
|
||||||
|
|
||||||
const { isDark } = usePreferences();
|
const { isDark } = usePreferences();
|
||||||
|
|
||||||
const tokenTheme = computed(() => {
|
const tokenTheme = computed(() => {
|
||||||
@ -35,7 +31,7 @@ const tokenTheme = computed(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<GlobalProvider>
|
<GlobalProvider>
|
||||||
<ConfigProvider :locale="zhCN" :theme="tokenTheme">
|
<ConfigProvider :locale="antdLocale" :theme="tokenTheme">
|
||||||
<App>
|
<App>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</App>
|
</App>
|
||||||
|
@ -4,6 +4,7 @@ import { setupI18n } from '@vben/locales';
|
|||||||
import '@vben/styles';
|
import '@vben/styles';
|
||||||
import { preferences } from '@vben-core/preferences';
|
import { preferences } from '@vben-core/preferences';
|
||||||
|
|
||||||
|
import { loadThirdPartyMessage } from '#/forward';
|
||||||
import { setupStore } from '#/store';
|
import { setupStore } from '#/store';
|
||||||
|
|
||||||
import App from './app.vue';
|
import App from './app.vue';
|
||||||
@ -13,7 +14,10 @@ async function bootstrap(namespace: string) {
|
|||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
// 国际化 i18n 配置
|
// 国际化 i18n 配置
|
||||||
await setupI18n(app, { defaultLocale: preferences.app.locale });
|
await setupI18n(app, {
|
||||||
|
defaultLocale: preferences.app.locale,
|
||||||
|
loadThirdPartyMessage,
|
||||||
|
});
|
||||||
|
|
||||||
// 配置 pinia-store
|
// 配置 pinia-store
|
||||||
await setupStore(app, { namespace });
|
await setupStore(app, { namespace });
|
||||||
|
11
apps/web-antd/src/forward/README.md
Normal file
11
apps/web-antd/src/forward/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# forward
|
||||||
|
|
||||||
|
用于扩展、转发大仓的包以及其他功能,方便在app内自定义不同的逻辑
|
||||||
|
|
||||||
|
## request
|
||||||
|
|
||||||
|
用于扩展请求的功能,例如添加header、错误响应等
|
||||||
|
|
||||||
|
## locale
|
||||||
|
|
||||||
|
用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换
|
@ -1 +1,2 @@
|
|||||||
|
export * from './locale';
|
||||||
export * from './request';
|
export * from './request';
|
||||||
|
48
apps/web-antd/src/forward/locale.ts
Normal file
48
apps/web-antd/src/forward/locale.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import type { SupportedLanguagesType } from '@vben/types';
|
||||||
|
import type { Locale } from 'ant-design-vue/es/locale';
|
||||||
|
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import defaultLocale from 'ant-design-vue/es/locale/zh_CN';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
const antdLocale = ref<Locale>(defaultLocale);
|
||||||
|
|
||||||
|
async function loadDayjsLocale(lang: SupportedLanguagesType) {
|
||||||
|
let locale;
|
||||||
|
switch (lang) {
|
||||||
|
case 'zh-CN': {
|
||||||
|
locale = await import('dayjs/locale/zh-cn');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'en-US': {
|
||||||
|
locale = await import('dayjs/locale/en');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
locale = await import('dayjs/locale/en');
|
||||||
|
} // 默认使用英语
|
||||||
|
}
|
||||||
|
dayjs.locale(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadAntdLocale(lang: SupportedLanguagesType) {
|
||||||
|
switch (lang) {
|
||||||
|
case 'zh-CN': {
|
||||||
|
antdLocale.value = defaultLocale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'en-US': {
|
||||||
|
antdLocale.value = (await import(
|
||||||
|
'ant-design-vue/es/locale/en_US'
|
||||||
|
)) as unknown as Locale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadThirdPartyMessage(land: SupportedLanguagesType) {
|
||||||
|
await Promise.all([loadAntdLocale(land), loadDayjsLocale(land)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { antdLocale, loadThirdPartyMessage };
|
@ -2,7 +2,7 @@ const BasicLayout = () => import('./basic.vue');
|
|||||||
|
|
||||||
const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);
|
const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);
|
||||||
|
|
||||||
const AuthPageLayoutType = () =>
|
const AuthPageLayout = () =>
|
||||||
import('@vben/layouts').then((m) => m.AuthPageLayoutType);
|
import('@vben/layouts').then((m) => m.AuthPageLayout);
|
||||||
|
|
||||||
export { AuthPageLayoutType, BasicLayout, IFrameView };
|
export { AuthPageLayout, BasicLayout, IFrameView };
|
||||||
|
@ -3,7 +3,7 @@ import type { RouteRecordRaw } from 'vue-router';
|
|||||||
import { DEFAULT_HOME_PATH } from '@vben/constants';
|
import { DEFAULT_HOME_PATH } from '@vben/constants';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import { AuthPageLayoutType } from '#/layouts';
|
import { AuthPageLayout } from '#/layouts';
|
||||||
import Login from '#/views/_essential/authentication/login.vue';
|
import Login from '#/views/_essential/authentication/login.vue';
|
||||||
|
|
||||||
/** 全局404页面 */
|
/** 全局404页面 */
|
||||||
@ -30,7 +30,7 @@ const essentialsRoutes: RouteRecordRaw[] = [
|
|||||||
redirect: DEFAULT_HOME_PATH,
|
redirect: DEFAULT_HOME_PATH,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: AuthPageLayoutType,
|
component: AuthPageLayout,
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Authentication',
|
title: 'Authentication',
|
||||||
},
|
},
|
||||||
|
@ -495,11 +495,12 @@
|
|||||||
padding-right: 12px !important;
|
padding-right: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.is-active):hover {
|
// &:not(.is-active):hover {
|
||||||
|
&:hover {
|
||||||
color: var(--menu-submenu-hover-color);
|
color: var(--menu-submenu-hover-color);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: var(--menu-submenu-hover-background-color);
|
background: var(--menu-submenu-hover-background-color) !important;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: var(--menu-submenu-hover-color);
|
fill: var(--menu-submenu-hover-color);
|
||||||
|
@ -1 +1 @@
|
|||||||
export { default as AuthPageLayoutType } from './authentication.vue';
|
export { default as AuthPageLayout } from './authentication.vue';
|
||||||
|
@ -43,7 +43,7 @@ function setI18nLanguage(locale: Locale) {
|
|||||||
* Load locale messages
|
* Load locale messages
|
||||||
* @param lang
|
* @param lang
|
||||||
*/
|
*/
|
||||||
async function loadLocaleMessages(lang: SupportedLanguagesType) {
|
async function loadI18nMessages(lang: SupportedLanguagesType) {
|
||||||
if (unref(i18n.global.locale) === lang) {
|
if (unref(i18n.global.locale) === lang) {
|
||||||
return setI18nLanguage(lang);
|
return setI18nLanguage(lang);
|
||||||
}
|
}
|
||||||
@ -59,4 +59,4 @@ async function loadLocaleMessages(lang: SupportedLanguagesType) {
|
|||||||
return setI18nLanguage(lang);
|
return setI18nLanguage(lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { i18n, loadLocaleMessages, setI18nLanguage };
|
export { i18n, loadI18nMessages, setI18nLanguage };
|
||||||
|
@ -1,13 +1,22 @@
|
|||||||
import type { LocaleSetupOptions } from './typing';
|
import type { LocaleSetupOptions, SupportedLanguagesType } from './typing';
|
||||||
|
|
||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
|
|
||||||
import { i18n, loadLocaleMessages } from './i18n';
|
import { i18n, loadI18nMessages } from './i18n';
|
||||||
|
|
||||||
const $t = i18n.global.t;
|
const $t = i18n.global.t;
|
||||||
|
|
||||||
|
let loadThirdPartyMessage: (lang: SupportedLanguagesType) => Promise<void>;
|
||||||
|
|
||||||
|
async function loadLocaleMessages(lang: SupportedLanguagesType) {
|
||||||
|
await loadI18nMessages(lang);
|
||||||
|
await loadThirdPartyMessage(lang);
|
||||||
|
}
|
||||||
|
|
||||||
async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
|
async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
|
||||||
const { defaultLocale = 'zh-CN' } = options;
|
const { defaultLocale = 'zh-CN' } = options;
|
||||||
|
// app可以自行扩展一些第三方库和组件库的国际化
|
||||||
|
loadThirdPartyMessage = options.loadThirdPartyMessage || (async () => {});
|
||||||
app.use(i18n);
|
app.use(i18n);
|
||||||
await loadLocaleMessages(defaultLocale);
|
await loadLocaleMessages(defaultLocale);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,12 @@ interface LocaleSetupOptions {
|
|||||||
* @default zh-CN
|
* @default zh-CN
|
||||||
*/
|
*/
|
||||||
defaultLocale?: SupportedLanguagesType;
|
defaultLocale?: SupportedLanguagesType;
|
||||||
|
/**
|
||||||
|
* Load third-party library messages
|
||||||
|
* @param lang
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
loadThirdPartyMessage?: (lang: SupportedLanguagesType) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { ImportLocaleFn, LocaleSetupOptions, SupportedLanguagesType };
|
export type { ImportLocaleFn, LocaleSetupOptions, SupportedLanguagesType };
|
||||||
|
Loading…
Reference in New Issue
Block a user