wip: support multilingual configuration

This commit is contained in:
vben
2020-11-19 23:01:27 +08:00
parent 3a651767fe
commit 8882d4e7ea
25 changed files with 372 additions and 135 deletions

View 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
View File

@@ -0,0 +1,3 @@
import messages from 'globby?locale!/@/locales/lang/**/*.@(ts)';
export default messages;

View File

@@ -0,0 +1,3 @@
export default {
someentry: 'some text',
};

View File

@@ -0,0 +1,3 @@
export default {
some: 'Get Out',
};

View File

@@ -0,0 +1,3 @@
export default {
button: 'Login',
};

View File

@@ -0,0 +1,3 @@
export default {
someentry: 'some text',
};

View File

@@ -0,0 +1,3 @@
export default {
some: 'Get Out',
};

View File

@@ -0,0 +1,7 @@
export default {
button: 'Login',
validation: {
account: 'Required Field account',
password: 'Required Field password',
},
};

View File

@@ -0,0 +1,3 @@
export default {
someentry: '一些文本',
};

View File

@@ -0,0 +1,3 @@
export default {
some: '出去',
};

View File

@@ -0,0 +1,3 @@
export default {
button: '登录',
};

1
src/locales/types.ts Normal file
View File

@@ -0,0 +1 @@
export type LocaleType = 'zhCN' | 'en' | 'ru' | 'ja';

View File

@@ -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);

View File

@@ -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
View 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 dont 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);
}

View File

@@ -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>) {

View File

@@ -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;
// 左侧菜单背景色

View File

@@ -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;

View File

@@ -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,
};
},
});