mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 15:41:32 +08:00
wip: support multilingual configuration
This commit is contained in:
21
src/hooks/web/useLocale.ts
Normal file
21
src/hooks/web/useLocale.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { LocaleType } from '/@/locales/types';
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
|
||||
export function useLocale() {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getLocale(): string {
|
||||
return appStore.getProjectConfig.locale;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
*/
|
||||
async function changeLocale(locale: LocaleType): Promise<void> {
|
||||
appStore.commitProjectConfigState({ locale: locale });
|
||||
}
|
||||
|
||||
return { getLocale, changeLocale };
|
||||
}
|
3
src/locales/index.ts
Normal file
3
src/locales/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import messages from 'globby?locale!/@/locales/lang/**/*.@(ts)';
|
||||
|
||||
export default messages;
|
3
src/locales/lang/en/routes/menus/dashboard.ts
Normal file
3
src/locales/lang/en/routes/menus/dashboard.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
someentry: 'some text',
|
||||
};
|
3
src/locales/lang/en/system/basic.ts
Normal file
3
src/locales/lang/en/system/basic.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
some: 'Get Out',
|
||||
};
|
3
src/locales/lang/en/system/login.ts
Normal file
3
src/locales/lang/en/system/login.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
button: 'Login',
|
||||
};
|
3
src/locales/lang/ru/routes/menus/dashboard.ts
Normal file
3
src/locales/lang/ru/routes/menus/dashboard.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
someentry: 'some text',
|
||||
};
|
3
src/locales/lang/ru/system/basic.ts
Normal file
3
src/locales/lang/ru/system/basic.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
some: 'Get Out',
|
||||
};
|
7
src/locales/lang/ru/system/login.ts
Normal file
7
src/locales/lang/ru/system/login.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
button: 'Login',
|
||||
validation: {
|
||||
account: 'Required Field account',
|
||||
password: 'Required Field password',
|
||||
},
|
||||
};
|
3
src/locales/lang/zhCN/routes/menus/dashboard.ts
Normal file
3
src/locales/lang/zhCN/routes/menus/dashboard.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
someentry: '一些文本',
|
||||
};
|
3
src/locales/lang/zhCN/system/basic.ts
Normal file
3
src/locales/lang/zhCN/system/basic.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
some: '出去',
|
||||
};
|
3
src/locales/lang/zhCN/system/login.ts
Normal file
3
src/locales/lang/zhCN/system/login.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
button: '登录',
|
||||
};
|
1
src/locales/types.ts
Normal file
1
src/locales/types.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type LocaleType = 'zhCN' | 'en' | 'ru' | 'ja';
|
@@ -5,6 +5,7 @@ import { setupStore } from '/@/store';
|
||||
import { setupAntd } from '/@/setup/ant-design-vue';
|
||||
import { setupErrorHandle } from '/@/setup/error-handle';
|
||||
import { setupGlobDirectives } from '/@/setup/directives';
|
||||
import { setupI18n } from '/@/setup/i18n';
|
||||
|
||||
import { setupProdMockServer } from '../mock/_createProductionServer';
|
||||
import { setApp } from '/@/setup/App';
|
||||
@@ -15,11 +16,16 @@ import { isDevMode, isProdMode, isUseMock } from '/@/utils/env';
|
||||
|
||||
import '/@/design/index.less';
|
||||
|
||||
import '/@/locales/index';
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
// Configure component library
|
||||
setupAntd(app);
|
||||
|
||||
// Multilingual configuration
|
||||
setupI18n(app);
|
||||
|
||||
// Configure routing
|
||||
setupRouter(app);
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import { isProdMode } from '/@/utils/env';
|
||||
|
||||
// ! You need to clear the browser cache after the change
|
||||
const setting: ProjectConfig = {
|
||||
locale: 'en',
|
||||
// color
|
||||
// TODO 主题色
|
||||
themeColor: primaryColor,
|
||||
|
35
src/setup/i18n/index.ts
Normal file
35
src/setup/i18n/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { App } from 'vue';
|
||||
import type { I18n, Locale, I18nOptions } from 'vue-i18n';
|
||||
|
||||
import { createI18n } from 'vue-i18n';
|
||||
import localeMessages from '/@/locales';
|
||||
import { useLocale } from '/@/hooks/web/useLocale';
|
||||
|
||||
const { getLocale } = useLocale();
|
||||
|
||||
const localeData: I18nOptions = {
|
||||
legacy: false,
|
||||
locale: getLocale(),
|
||||
// TODO: setting fallback inside settings
|
||||
fallbackLocale: 'en',
|
||||
messages: localeMessages,
|
||||
// availableLocales: ['ru'],
|
||||
sync: true, //If you don’t want to inherit locale from global scope, you need to set sync of i18n component option to false.
|
||||
silentTranslationWarn: false, // true - warning off
|
||||
silentFallbackWarn: true,
|
||||
};
|
||||
|
||||
let i18n: I18n;
|
||||
|
||||
// setup i18n instance with glob
|
||||
export function setupI18n(app: App) {
|
||||
i18n = createI18n(localeData) as I18n;
|
||||
setI18nLanguage(getLocale());
|
||||
app.use(i18n);
|
||||
}
|
||||
|
||||
export function setI18nLanguage(locale: Locale): void {
|
||||
// @ts-ignore
|
||||
i18n.global.locale.value = locale;
|
||||
// i18n.global.setLocaleMessage(locale, messages);
|
||||
}
|
@@ -1,16 +1,19 @@
|
||||
import type { App } from 'vue';
|
||||
import { createStore, createLogger, Plugin } from 'vuex';
|
||||
import {
|
||||
createStore,
|
||||
// createLogger, Plugin
|
||||
} from 'vuex';
|
||||
import { config } from 'vuex-module-decorators';
|
||||
import { isDevMode } from '/@/utils/env';
|
||||
|
||||
config.rawError = true;
|
||||
const isDev = isDevMode();
|
||||
const plugins: Plugin<any>[] = isDev ? [createLogger()] : [];
|
||||
// const plugins: Plugin<any>[] = isDev ? [createLogger()] : [];
|
||||
|
||||
const store = createStore({
|
||||
// modules: {},
|
||||
strict: isDev,
|
||||
plugins,
|
||||
// plugins,
|
||||
});
|
||||
|
||||
export function setupStore(app: App<Element>) {
|
||||
|
3
src/types/config.d.ts
vendored
3
src/types/config.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
// 左侧菜单, 顶部菜单
|
||||
import { MenuTypeEnum, MenuModeEnum, TriggerEnum } from '/@/enums/menuEnum';
|
||||
import { ContentEnum, PermissionModeEnum, ThemeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
|
||||
|
||||
import type { LocaleType } from '/@/locales/types';
|
||||
export interface MessageSetting {
|
||||
title: string;
|
||||
// 取消按钮的文字,
|
||||
@@ -55,6 +55,7 @@ export interface HeaderSetting {
|
||||
showNotice: boolean;
|
||||
}
|
||||
export interface ProjectConfig {
|
||||
locale: LocaleType;
|
||||
// header背景色
|
||||
headerBgColor: string;
|
||||
// 左侧菜单背景色
|
||||
|
2
src/types/module.d.ts
vendored
2
src/types/module.d.ts
vendored
@@ -4,4 +4,6 @@ declare module 'globby!/@/router/routes/modules/**/*.@(ts)';
|
||||
|
||||
declare module 'globby!/@/router/menus/modules/**/*.@(ts)';
|
||||
|
||||
declare module 'globby?locale!/@/locales/lang/**/*.@(ts)';
|
||||
|
||||
declare const React: string;
|
||||
|
@@ -11,14 +11,14 @@
|
||||
|
||||
<a-form class="mx-auto mt-10" :model="formData" :rules="formRules" ref="formRef">
|
||||
<a-form-item name="account">
|
||||
<a-input size="large" v-model:value="formData.account" placeholder="Username: vben" />
|
||||
<a-input size="large" v-model:value="formData.account" placeholder="username: vben" />
|
||||
</a-form-item>
|
||||
<a-form-item name="password">
|
||||
<a-input-password
|
||||
size="large"
|
||||
visibilityToggle
|
||||
v-model:value="formData.password"
|
||||
placeholder="Password: 123456"
|
||||
placeholder="password: 123456"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<!-- 未做逻辑,需要自行处理 -->
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-checkbox v-model:checked="autoLogin" size="small">自动登录</a-checkbox>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item :style="{ 'text-align': 'right' }">
|
||||
<!-- 未做逻辑,需要自行处理 -->
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-button type="link" size="small">忘记密码</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
@@ -47,7 +47,7 @@
|
||||
:block="true"
|
||||
@click="login"
|
||||
:loading="formState.loading"
|
||||
>登录</a-button
|
||||
>{{ t('system.login.button') }}</a-button
|
||||
>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -57,20 +57,15 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {
|
||||
defineComponent,
|
||||
reactive,
|
||||
ref,
|
||||
unref,
|
||||
toRaw,
|
||||
// computed
|
||||
} from 'vue';
|
||||
import { defineComponent, reactive, ref, unref, toRaw } from 'vue';
|
||||
import { Checkbox } from 'ant-design-vue';
|
||||
|
||||
import Button from '/@/components/Button/index.vue';
|
||||
// import { BasicDragVerify, DragVerifyActionType } from '/@/components/Verify/index';
|
||||
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
// import { appStore } from '/@/store/modules/app';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useSetting } from '/@/hooks/core/useSetting';
|
||||
@@ -139,7 +134,7 @@
|
||||
formState.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
const { t } = useI18n();
|
||||
return {
|
||||
formRef,
|
||||
// verifyRef,
|
||||
@@ -151,6 +146,7 @@
|
||||
// openLoginVerify: openLoginVerifyRef,
|
||||
title: globSetting && globSetting.title,
|
||||
logo,
|
||||
t,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
Reference in New Issue
Block a user