Skip to content

Commit

Permalink
wip: multi-language support
Browse files Browse the repository at this point in the history
  • Loading branch information
anncwb committed Nov 22, 2020
1 parent b49950a commit 737b1b1
Show file tree
Hide file tree
Showing 59 changed files with 512 additions and 272 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.zh_CN.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Wip

### 🎫 Chores

- 移除 messageSetting 配置

## 2.0.0-rc.11 (2020-11-18)

### ✨ Features
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"ant-design-vue": "2.0.0-beta.15",
"apexcharts": "3.22.0",
"axios": "^0.21.0",
"crypto-es": "^1.2.6",
"echarts": "^4.9.0",
"lodash-es": "^4.17.15",
"mockjs": "^1.1.0",
Expand Down
21 changes: 12 additions & 9 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<template>
<ConfigProvider v-bind="lockEvent" :locale="zhCN" :transform-cell-text="transformCellText">
<ConfigProvider
v-bind="lockEvent"
:locale="antConfigLocale"
:transform-cell-text="transformCellText"
>
<router-view />
</ConfigProvider>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { ConfigProvider } from 'ant-design-vue';
import { createBreakpointListen } from '/@/hooks/event/useBreakpoint';
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import moment from 'moment';
import 'moment/dist/locale/zh-cn';
import { getConfigProvider, initAppConfigStore } from '/@/setup/App';
import { useLockPage } from '/@/hooks/web/useLockPage';
moment.locale('zh-cn');
import { useLockPage } from '/@/hooks/web/useLockPage';
import { useLocale } from '/@/hooks/web/useLocale';
import { createBreakpointListen } from '/@/hooks/event/useBreakpoint';
export default defineComponent({
name: 'App',
Expand All @@ -34,9 +34,12 @@
// Create a lock screen monitor
const lockEvent = useLockPage();
// support Multi-language
const { antConfigLocale } = useLocale();
return {
transformCellText,
zhCN,
antConfigLocale,
lockEvent,
};
},
Expand Down
3 changes: 3 additions & 0 deletions src/components/Application/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AppLocalPicker from './src/AppLocalPicker.vue';

export { AppLocalPicker };
53 changes: 53 additions & 0 deletions src/components/Application/src/AppLocalPicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<Dropdown
:trigger="['click']"
:dropMenuList="localeList"
:selectedKeys="selectedKeys"
@menuEvent="handleMenuEvent"
>
<GlobalOutlined class="app-locale" />
</Dropdown>
</template>
<script lang="ts">
import { defineComponent, ref, watchEffect, unref } from 'vue';
import { Dropdown, DropMenu } from '/@/components/Dropdown';
import { GlobalOutlined } from '@ant-design/icons-vue';
import { useLocale } from '/@/hooks/web/useLocale';
import { useLocaleSetting } from '/@/settings/use/useLocaleSetting';
import { LocaleType } from '/@/locales/types';
export default defineComponent({
name: 'AppLocalPicker',
components: { GlobalOutlined, Dropdown },
setup() {
const { localeList } = useLocaleSetting();
const selectedKeys = ref<string[]>([]);
const { changeLocale, getLang } = useLocale();
watchEffect(() => {
selectedKeys.value = [unref(getLang)];
});
function toggleLocale(lang: LocaleType | string) {
changeLocale(lang as LocaleType);
selectedKeys.value = [lang as string];
}
function handleMenuEvent(menu: DropMenu) {
toggleLocale(menu.event as string);
}
return { localeList, handleMenuEvent, selectedKeys };
},
});
</script>

<style lang="less" scoped>
.app-locale {
cursor: pointer;
}
</style>
4 changes: 2 additions & 2 deletions src/components/Dropdown/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default as Dropdown } from './Dropdown';
export * from './types';
export { default as Dropdown } from './src/Dropdown';
export * from './src/types';
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
import { defineComponent, computed, unref } from 'vue';
import { Dropdown, Menu } from 'ant-design-vue';
import { Dropdown, Menu, Divider } from 'ant-design-vue';

import Icon from '/@/components/Icon/index';

import { basicDropdownProps } from './props';
import { getSlot } from '/@/utils/helper/tsxHelper';
import { Trigger } from './types';

export default defineComponent({
name: 'Dropdown',
props: basicDropdownProps,
emits: ['menuEvent'],
setup(props, { slots, emit, attrs }) {
const getMenuList = computed(() => props.dropMenuList);

function handleClickMenu({ key }: any) {
const menu = unref(getMenuList)[key];
const menu = unref(getMenuList).find((item) => item.event === key);
emit('menuEvent', menu);
}

function renderMenus() {
return (
<Menu onClick={handleClickMenu}>
<Menu onClick={handleClickMenu} selectedKeys={props.selectedKeys}>
{() => (
<>
{unref(getMenuList).map((item, index) => {
const { disabled, icon, text, divider } = item;

const { disabled, icon, text, divider, event } = item;
return [
<Menu.Item key={`${index}`} disabled={disabled}>
<Menu.Item key={`${event}`} disabled={disabled}>
{() => (
<>
{icon && <Icon icon={icon} />}
<span class="ml-1">{text}</span>
</>
)}
</Menu.Item>,
// @ts-ignore
divider && <Menu.Divider key={`d-${index}`} />,
divider && <Divider key={`d-${index}`} />,
];
})}
</>
Expand All @@ -45,7 +45,7 @@ export default defineComponent({
}

return () => (
<Dropdown trigger={props.trigger as any} {...attrs}>
<Dropdown trigger={props.trigger as Trigger[]} {...attrs}>
{{
default: () => <span>{getSlot(slots)}</span>,
overlay: () => renderMenus(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { PropType } from 'vue';
import type { DropMenu } from './types';

export const dropdownProps = {
/**
Expand All @@ -15,7 +16,11 @@ export const dropdownProps = {
};
export const basicDropdownProps = Object.assign({}, dropdownProps, {
dropMenuList: {
type: Array as PropType<any[]>,
type: Array as PropType<DropMenu[]>,
default: () => [],
},
selectedKeys: {
type: Array as PropType<string[]>,
default: () => [],
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export interface DropMenu {
disabled?: boolean;
divider?: boolean;
}

export type Trigger = 'click' | 'hover' | 'contextMenu';
16 changes: 0 additions & 16 deletions src/hooks/web/useI18n.ts

This file was deleted.

79 changes: 66 additions & 13 deletions src/hooks/web/useLocale.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,74 @@
/**
* Multi-language related operations
*/
import type { LocaleType } from '/@/locales/types';
import { appStore } from '/@/store/modules/app';

import { unref, ref } from 'vue';

import { getI18n } from '/@/setup/i18n';

import { useLocaleSetting } from '/@/settings/use/useLocaleSetting';

import moment from 'moment';

import 'moment/dist/locale/zh-cn';

moment.locale('zh-cn');

const antConfigLocaleRef = ref<any>(null);

export function useLocale() {
/**
*
*/
function getLocale(): string {
return appStore.getProjectConfig.locale;
const { getLang, getLocale, setLocale: setLocalSetting } = useLocaleSetting();

// Switching the language will change the locale of useI18n
// And submit to configuration modification
function changeLocale(lang: LocaleType): void {
(getI18n().global.locale as any).value = lang;
setLocalSetting({ lang });
// i18n.global.setLocaleMessage(locale, messages);

antConfigLocaleRef.value = { a: 1 };
switch (lang) {
// Simplified Chinese
case 'zh_CN':
import('ant-design-vue/es/locale/zh_CN').then((locale) => {
antConfigLocaleRef.value = locale.default;
});

moment.locale('cn');
break;
// English
case 'en':
import('ant-design-vue/es/locale/en_US').then((locale) => {
antConfigLocaleRef.value = locale.default;
});
moment.locale('en-us');
break;

// other
default:
break;
}
}

/**
*
* @param locale
*/
async function changeLocale(locale: LocaleType): Promise<void> {
appStore.commitProjectConfigState({ locale: locale });
// initialization
function setupLocale() {
const lang = unref(getLang);
lang && changeLocale(lang);
}

return { getLocale, changeLocale };
return {
setupLocale,
getLocale,
getLang,
changeLocale,
antConfigLocale: antConfigLocaleRef,
};
}

/**
* For non-setup use
*/
export function useExternalI18n() {
return getI18n().global;
}
4 changes: 0 additions & 4 deletions src/hooks/web/useMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { ModalFunc, ModalFuncProps } from 'ant-design-vue/lib/modal/Modal';
import { Modal, message as Message, notification } from 'ant-design-vue';
import { InfoCircleFilled, CheckCircleFilled, CloseCircleFilled } from '@ant-design/icons-vue';

import { useSetting } from '/@/hooks/core/useSetting';
import { ArgsProps, ConfigProps } from 'ant-design-vue/lib/notification';

export interface NotifyApi {
Expand Down Expand Up @@ -33,8 +32,6 @@ interface ConfirmOptions {
warning: ModalFunc;
}

const { projectSetting } = useSetting();

function getIcon(iconType: string) {
if (iconType === 'warning') {
return <InfoCircleFilled class="modal-icon-warning" />;
Expand All @@ -60,7 +57,6 @@ function createConfirm(options: ModalOptionsEx): ConfirmOptions {
const opt: ModalFuncProps = {
centered: true,
icon: getIcon(iconType),
...projectSetting.messageSetting,
...options,
};
return Modal.confirm(opt) as any;
Expand Down
3 changes: 1 addition & 2 deletions src/layouts/default/setting/SettingDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Button from '/@/components/Button/index.vue';
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
import { appStore } from '/@/store/modules/app';
import { userStore } from '/@/store/modules/user';
import { ProjectConfig } from '/@/types/config';

import { useMessage } from '/@/hooks/web/useMessage';
Expand Down Expand Up @@ -97,7 +96,7 @@ export default defineComponent({

function handleClearAndRedo() {
localStorage.clear();
userStore.resumeAllState();
appStore.resumeAllState();
location.reload();
}

Expand Down
4 changes: 2 additions & 2 deletions src/layouts/logo/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<script lang="ts">
import { computed, defineComponent, PropType, ref, watch } from 'vue';
// hooks
import { useSetting } from '/@/hooks/core/useSetting';
import { useGlobSetting } from '/@/settings/use';
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
import { useGo } from '/@/hooks/web/usePage';
Expand All @@ -30,7 +30,7 @@
},
setup(props) {
const showRef = ref<boolean>(!!props.showTitle);
const { globSetting } = useSetting();
const globSetting = useGlobSetting();
const go = useGo();
function handleGoHome() {
Expand Down
4 changes: 2 additions & 2 deletions src/layouts/page/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { RouterView, RouteLocation } from 'vue-router';
import FrameLayout from '/@/layouts/iframe/index.vue';

import { useTransition } from './useTransition';
import { useSetting } from '/@/hooks/core/useSetting';
import { useProjectSetting } from '/@/settings/use';

import { tabStore } from '/@/store/modules/tab';
import { appStore } from '/@/store/modules/app';
Expand All @@ -29,7 +29,7 @@ export default defineComponent({
const { on: transitionOn } = useTransition();
on = transitionOn;
}
const { projectSetting } = useSetting();
const projectSetting = useProjectSetting();
return () => {
const {
routerTransition,
Expand Down
Loading

0 comments on commit 737b1b1

Please sign in to comment.