feat: 切换语言

This commit is contained in:
万纯 2020-12-31 16:10:30 +08:00
parent 48c1234725
commit f01538ba8b
11 changed files with 428 additions and 19 deletions

View File

@ -14,6 +14,7 @@
"author": "",
"license": "MIT",
"peerDependencies": {
"vue": "^3.0.4",
"@webank/fes": "^2.0.0"
}
}

View File

@ -16,6 +16,7 @@
"peerDependencies": {
"vue": "^3.0.4",
"@webank/fes": "^2.0.0",
"ant-design-vue": "2.0.0-rc.3"
"ant-design-vue": "2.0.0-rc.3",
"@ant-design/icons-vue": "^5.1.6"
}
}

View File

@ -17,7 +17,10 @@
</a-layout-sider>
<a-layout>
<a-layout-header v-if="routeLayout" class="layout-header">
<slot name="userCenter"></slot>
<div class="layout-header-user">
<slot name="userCenter"></slot>
</div>
<SelectLang />
</a-layout-header>
<a-layout-content class="layout-content">
<slot></slot>
@ -31,10 +34,10 @@
<script>
import { ref, computed } from 'vue';
import { useRoute } from '@webank/fes';
import { useRoute, SelectLang } from '@webank/fes';
import Layout from 'ant-design-vue/lib/layout';
import 'ant-design-vue/lib/layout/style';
import Menu from './Menu.vue';
import Menu from './Menu';
export default {
components: {
@ -43,7 +46,8 @@ export default {
[Layout.Content.name]: Layout.Content,
[Layout.Header.name]: Layout.Header,
[Layout.Footer.name]: Layout.Footer,
Menu
Menu,
SelectLang: SelectLang || (<></>)
},
props: {
menus: {
@ -89,7 +93,7 @@ export default {
default: 200
}
},
setup(props, content) {
setup() {
const route = useRoute();
const routeLayout = computed(() => {
const _routeLayout = route.meta.layout;
@ -136,10 +140,15 @@ export default {
}
}
.layout-header {
display: flex;
align-items: center;
height: 48px;
line-height: 48px;
background: #fff;
padding: 0;
padding: 0 24px;
.layout-header-user {
flex: 1
}
}
.layout-content {
position: relative;

View File

@ -45,7 +45,7 @@
</template>
<script>
import { ref, toRefs, computed } from 'vue';
import { toRefs, computed } from 'vue';
import { useRoute, useRouter } from '@webank/fes';
import Menu from 'ant-design-vue/lib/menu';
import 'ant-design-vue/lib/menu/style';

View File

@ -18,6 +18,9 @@
"vue-i18n": "^9.0.0-beta.15"
},
"peerDependencies": {
"@webank/fes": "^2.0.0"
"vue": "^3.0.4",
"@webank/fes": "^2.0.0",
"ant-design-vue": "2.0.0-rc.3",
"@ant-design/icons-vue": "^5.1.6"
}
}

View File

@ -22,6 +22,10 @@ export default (api) => {
const absRuntimeFilePath = join(namespace, 'runtime.js');
const selectLangComponentFilePath = join(namespace, 'views/SelectLang.vue');
const langConfigFilePath = join(namespace, 'langUConfigMap');
function getLocaleFileBasePath() {
return join(api.paths.absSrcPath, api.config.singular ? 'locale' : 'locales');
}
@ -56,16 +60,30 @@ export default (api) => {
'utf-8'
)
});
api.writeTmpFile({
path: langConfigFilePath,
content: readFileSync(
join(__dirname, 'template/langUConfigMap.js'),
'utf-8'
)
});
api.writeTmpFile({
path: selectLangComponentFilePath,
content: readFileSync(
join(__dirname, 'views/SelectLang.vue'),
'utf-8'
)
});
});
api.addPluginExports(() => [
{
specifiers: ['useI18n', 'setLocale'],
specifiers: ['useI18n', 'setLocale', 'SelectLang'],
source: absoluteFilePath
}
]);
// api.addRuntimePluginKey(() => 'access');
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
};

View File

@ -7,6 +7,7 @@
// 所有插件使用一个语言和配置
import { createI18n, useI18n } from 'vue-i18n/dist/vue-i18n.esm-bundler.js';
import SelectLang from "./views/SelectLang"
const defaultLangUConfigMap = {
'ar-EG': {
@ -348,4 +349,4 @@ const install = (app)=>{
app.use(i18n);
}
export { useI18n, setLocale, addLocale, getAllLocales, install }
export { useI18n, setLocale, SelectLang, install }

View File

@ -0,0 +1,314 @@
export default {
'ar-EG': {
lang: 'ar-EG',
label: 'العربية',
icon: '🇪🇬',
title: 'لغة'
},
'az-AZ': {
lang: 'az-AZ',
label: 'Azərbaycan dili',
icon: '🇦🇿',
title: 'Dil'
},
'bg-BG': {
lang: 'bg-BG',
label: 'Български език',
icon: '🇧🇬',
title: 'език'
},
'ca-ES': {
lang: 'ca-ES',
label: 'Catalá',
icon: '🇨🇦',
title: 'llengua'
},
'cs-CZ': {
lang: 'cs-CZ',
label: 'Čeština',
icon: '🇨🇿',
title: 'Jazyk'
},
'da-DK': {
lang: 'da-DK',
label: 'Dansk',
icon: '🇩🇰',
title: 'Sprog'
},
'de-DE': {
lang: 'de-DE',
label: 'Deutsch',
icon: '🇩🇪',
title: 'Sprache'
},
'el-GR': {
lang: 'el-GR',
label: 'Ελληνικά',
icon: '🇬🇷',
title: 'Γλώσσα'
},
'en-GB': {
lang: 'en-GB',
label: 'English',
icon: '🇬🇧',
title: 'Language'
},
'en-US': {
lang: 'en-US',
label: 'English',
icon: '🇺🇸',
title: 'Language'
},
'es-ES': {
lang: 'es-ES',
label: 'Español',
icon: '🇪🇸',
title: 'Idioma'
},
'et-EE': {
lang: 'et-EE',
label: 'Eesti',
icon: '🇪🇪',
title: 'Keel'
},
'fa-IR': {
lang: 'fa-IR',
label: 'فارسی',
icon: '🇮🇷',
title: 'زبان'
},
'fi-FI': {
lang: 'fi-FI',
label: 'Suomi',
icon: '🇫🇮',
title: 'Kieli'
},
'fr-BE': {
lang: 'fr-BE',
label: 'Français',
icon: '🇧🇪',
title: 'Langue'
},
'fr-FR': {
lang: 'fr-FR',
label: 'Français',
icon: '🇫🇷',
title: 'Langue'
},
'ga-IE': {
lang: 'ga-IE',
label: 'Gaeilge',
icon: '🇮🇪',
title: 'Teanga'
},
'he-IL': {
lang: 'he-IL',
label: 'עברית',
icon: '🇮🇱',
title: 'שפה'
},
'hi-IN': {
lang: 'hi-IN',
label: 'हिन्दी, हिंदी',
icon: '🇮🇳',
title: 'भाषा: हिन्दी'
},
'hr-HR': {
lang: 'hr-HR',
label: 'Hrvatski jezik',
icon: '🇭🇷',
title: 'Jezik'
},
'hu-HU': {
lang: 'hu-HU',
label: 'Magyar',
icon: '🇭🇺',
title: 'Nyelv'
},
'hy-AM': {
lang: 'hu-HU',
label: 'Հայերեն',
icon: '🇦🇲',
title: 'Լեզու'
},
'id-ID': {
lang: 'id-ID',
label: 'Bahasa Indonesia',
icon: '🇮🇩',
title: 'Bahasa'
},
'it-IT': {
lang: 'it-IT',
label: 'Italiano',
icon: '🇮🇹',
title: 'Linguaggio'
},
'is-IS': {
lang: 'is-IS',
label: 'Íslenska',
icon: '🇮🇸',
title: 'Tungumál'
},
'ja-JP': {
lang: 'ja-JP',
label: '日本語',
icon: '🇯🇵',
title: '言語'
},
'ku-IQ': {
lang: 'ku-IQ',
label: 'کوردی',
icon: '🇮🇶',
title: 'Ziman'
},
'kn-IN': {
lang: 'zh-TW',
label: 'ಕನ್ನಡ',
icon: '🇮🇳',
title: 'ಭಾಷೆ'
},
'ko-KR': {
lang: 'ko-KR',
label: '한국어',
icon: '🇰🇷',
title: '언어'
},
'lv-LV': {
lang: 'lv-LV',
label: 'Latviešu valoda',
icon: '🇱🇮',
title: 'Kalba'
},
'mk-MK': {
lang: 'mk-MK',
label: 'македонски јазик',
icon: '🇲🇰',
title: 'Јазик'
},
'mn-MN': {
lang: 'mn-MN',
label: 'Монгол хэл',
icon: '🇲🇳',
title: 'Хэл'
},
'ms-MY': {
lang: 'ms-MY',
label: 'بهاس ملايو‎',
icon: '🇲🇾',
title: 'Bahasa'
},
'nb-NO': {
lang: 'nb-NO',
label: 'Norsk',
icon: '🇳🇴',
title: 'Språk'
},
'ne-NP': {
lang: 'ne-NP',
label: 'नेपाली',
icon: '🇳🇵',
title: 'भाषा'
},
'nl-BE': {
lang: 'nl-BE',
label: 'Vlaams',
icon: '🇧🇪',
title: 'Taal'
},
'nl-NL': {
lang: 'nl-NL',
label: 'Vlaams',
icon: '🇳🇱',
title: 'Taal'
},
'pt-BR': {
lang: 'pt-BR',
label: 'Português',
icon: '🇧🇷',
title: 'Idiomas'
},
'pt-PT': {
lang: 'pt-PT',
label: 'Português',
icon: '🇵🇹',
title: 'Idiomas'
},
'ro-RO': {
lang: 'ro-RO',
label: 'Română',
icon: '🇷🇴',
title: 'Limba'
},
'ru-RU': {
lang: 'ru-RU',
label: 'русский',
icon: '🇷🇺',
title: 'язык'
},
'sk-SK': {
lang: 'sk-SK',
label: 'Slovenčina',
icon: '🇸🇰',
title: 'Jazyk'
},
'sr-RS': {
lang: 'sr-RS',
label: 'српски језик',
icon: '🇸🇷',
title: 'Језик'
},
'sl-SI': {
lang: 'sl-SI',
label: 'Slovenščina',
icon: '🇸🇱',
title: 'Jezik'
},
'sv-SE': {
lang: 'sv-SE',
label: 'Svenska',
icon: '🇸🇪',
title: 'Språk'
},
'ta-IN': {
lang: 'ta-IN',
label: 'தமிழ்',
icon: '🇮🇳',
title: 'மொழி'
},
'th-TH': {
lang: 'th-TH',
label: 'ไทย',
icon: '🇹🇭',
title: 'ภาษา'
},
'tr-TR': {
lang: 'tr-TR',
label: 'Türkçe',
icon: '🇹🇷',
title: 'Dil'
},
'uk-UA': {
lang: 'uk-UA',
label: 'Українська',
icon: '🇺🇰',
title: 'Мова'
},
'vi-VN': {
lang: 'vi-VN',
label: 'Tiếng Việt',
icon: '🇻🇳',
title: 'Ngôn ngữ'
},
'zh-CN': {
lang: 'zh-CN',
label: '简体中文',
icon: '🇨🇳',
title: '语言'
},
'zh-TW': {
lang: 'zh-TW',
label: '繁体中文',
icon: '🇭🇰',
title: '語言'
}
};

View File

@ -0,0 +1,63 @@
<template>
<a-dropdown>
<GlobalOutlined />
<template #overlay>
<a-menu :selectedKeys="selectedKeys" @click="handleClick">
<a-menu-item
v-for="(item) in configs"
:key="item.lang"
class="lang-item"
>
<span class="lang-item-icon">{{item.icon}}</span>
<span class="lang-item-label">{{item.label}}</span>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
<script>
import Dropdown from 'ant-design-vue/lib/dropdown';
import Menu from 'ant-design-vue/lib/menu';
import 'ant-design-vue/lib/dropdown/style';
import 'ant-design-vue/lib/menu/style';
import { GlobalOutlined } from '@ant-design/icons-vue';
import { useI18n } from 'vue-i18n/dist/vue-i18n.esm-bundler';
import { reactive, computed } from 'vue';
import langUConfigMap from '../langUConfigMap';
export default {
components: {
[Dropdown.name]: Dropdown,
[Menu.name]: Menu,
[Menu.Item.name]: Menu.Item,
GlobalOutlined
},
setup() {
const { availableLocales, locale } = useI18n();
const selectedKeys = computed(() => [locale.value]);
const configs = reactive([]);
availableLocales.forEach((item) => {
configs.push(langUConfigMap[item] || {});
});
const handleClick = ({ key }) => {
locale.value = key;
};
return {
handleClick,
selectedKeys,
configs
};
}
};
</script>
<style lang="less">
.lang-item {
display: flex;
align-items: center;
.lang-item-label {
margin-left: 8px;
}
}
</style>

View File

@ -13,10 +13,11 @@
"keywords": [],
"author": "",
"license": "MIT",
"peerDependencies": {
"@webank/fes": "^2.0.0"
},
"dependencies": {
"@umijs/utils": "3.3.3"
},
"peerDependencies": {
"vue": "^3.0.4",
"@webank/fes": "^2.0.0"
}
}

View File

@ -14,19 +14,17 @@
<script>
import { ref, onMounted } from 'vue';
import {
useAccess, useModel, useRouter, useI18n, setLocale
useAccess, useRouter, useI18n, setLocale
} from '@webank/fes';
export default {
setup() {
const fes = ref('fes upgrade to vue3');
const accessOnepicess = useAccess('/onepiece');
const { initialState } = useModel('@@initialState');
const { t } = useI18n();
const router = useRouter();
onMounted(() => {
console.log(router);
console.log(initialState);
console.log('mounted1!!');
setTimeout(() => {
setLocale('en-US');