Commit 90d0b6a4605535068aa0443db0f756bb606e0b49
1 parent
f929fef0
feat(i18n) setup i18n config
Showing
11 changed files
with
208 additions
and
3 deletions
front-end/h5/package.json
front-end/h5/src/components/common/header/LangSelect.vue
0 → 100755
| 1 | +<template> | |
| 2 | + <a-dropdown> | |
| 3 | + <span class="action global-lang"> | |
| 4 | + <!-- <a-icon type="global" style="font-size: 16px"/> --> | |
| 5 | + {{langFlag}} | |
| 6 | + </span> | |
| 7 | + <a-menu slot="overlay" style="width: 150px;" @click="SwitchLang"> | |
| 8 | + <a-menu-item key="zh-CN"> | |
| 9 | + <a rel="noopener noreferrer"> | |
| 10 | + <span role="img" aria-label="简体中文">🇨🇳</span> 简体中文 | |
| 11 | + </a> | |
| 12 | + </a-menu-item> | |
| 13 | + <a-menu-item key="en-US"> | |
| 14 | + <a rel="noopener noreferrer"> | |
| 15 | + <span role="img" aria-label="English">🇺🇸</span> English | |
| 16 | + </a> | |
| 17 | + </a-menu-item> | |
| 18 | + </a-menu> | |
| 19 | + </a-dropdown> | |
| 20 | +</template> | |
| 21 | + | |
| 22 | +<script> | |
| 23 | +import langMixin from '@/mixins/i18n' | |
| 24 | + | |
| 25 | +export default { | |
| 26 | + name: 'LangSelect', | |
| 27 | + mixins: [langMixin], | |
| 28 | + computed: { | |
| 29 | + langFlag () { | |
| 30 | + switch (this.currentLang) { | |
| 31 | + case 'zh-CN': | |
| 32 | + return '🇨🇳' | |
| 33 | + case 'en-US': | |
| 34 | + return '🇺🇸' | |
| 35 | + default: | |
| 36 | + return '🇨🇳' | |
| 37 | + } | |
| 38 | + } | |
| 39 | + }, | |
| 40 | + methods: { | |
| 41 | + SwitchLang (row) { | |
| 42 | + this.setLang(row.key) | |
| 43 | + } | |
| 44 | + } | |
| 45 | +} | |
| 46 | +</script> | ... | ... |
front-end/h5/src/components/core/editor/index.js
| ... | ... | @@ -16,6 +16,7 @@ import PreviewDialog from './modals/preview.vue' |
| 16 | 16 | |
| 17 | 17 | import LogoOfHeader from '@/components/common/header/logo.js' |
| 18 | 18 | import ExternalLinksOfHeader from '@/components/common/header/links.js' |
| 19 | +import LangSelect from '@/components/common/header/LangSelect.vue' | |
| 19 | 20 | |
| 20 | 21 | const sidebarMenus = [ |
| 21 | 22 | { |
| ... | ... | @@ -85,7 +86,8 @@ export default { |
| 85 | 86 | name: 'Editor', |
| 86 | 87 | components: { |
| 87 | 88 | LogoOfHeader, |
| 88 | - ExternalLinksOfHeader | |
| 89 | + ExternalLinksOfHeader, | |
| 90 | + LangSelect | |
| 89 | 91 | }, |
| 90 | 92 | data: () => ({ |
| 91 | 93 | activeMenuKey: 'pluginList', |
| ... | ... | @@ -195,6 +197,7 @@ export default { |
| 195 | 197 | </a-menu-item> |
| 196 | 198 | </a-menu> |
| 197 | 199 | <ExternalLinksOfHeader /> |
| 200 | + <LangSelect /> | |
| 198 | 201 | </a-layout-header> |
| 199 | 202 | <a-layout> |
| 200 | 203 | <a-layout-sider width="160" style="background: #fff" collapsed> |
| ... | ... | @@ -217,7 +220,7 @@ export default { |
| 217 | 220 | <a-layout-sider width="240" theme='light' style={{ background: '#fff', padding: '12px' }}> |
| 218 | 221 | { this._renderMenuContent() } |
| 219 | 222 | </a-layout-sider> |
| 220 | - <a-layout style="padding: 0 24px 24px"> | |
| 223 | + <a-layout style="padding: 0 0 24px"> | |
| 221 | 224 | <a-layout-content style={{ padding: '24px', margin: 0, minHeight: '280px' }}> |
| 222 | 225 | <div style="text-align: center;"> |
| 223 | 226 | <a-radio-group | ... | ... |
front-end/h5/src/locales/index.js
0 → 100755
| 1 | +import Vue from 'vue' | |
| 2 | +import VueI18n from 'vue-i18n' | |
| 3 | +// default language | |
| 4 | +import enUSLang from './lang/en-US' | |
| 5 | +import zhCNLang from './lang/zh-CN' | |
| 6 | + | |
| 7 | +Vue.use(VueI18n) | |
| 8 | + | |
| 9 | +const messages = { | |
| 10 | + 'en-US': { | |
| 11 | + ...enUSLang | |
| 12 | + }, | |
| 13 | + 'zh-CN': { | |
| 14 | + ...zhCNLang | |
| 15 | + } | |
| 16 | +} | |
| 17 | +export const defaultLang = 'zh-CN' | |
| 18 | + | |
| 19 | +const i18n = new VueI18n({ | |
| 20 | + locale: defaultLang, | |
| 21 | + fallbackLocale: defaultLang, | |
| 22 | + messages | |
| 23 | +}) | |
| 24 | + | |
| 25 | +export default i18n | |
| 26 | + | |
| 27 | +const loadedLanguages = [defaultLang] | |
| 28 | + | |
| 29 | +function setI18nLanguage (lang) { | |
| 30 | + i18n.locale = lang | |
| 31 | + document.querySelector('html').setAttribute('lang', lang) | |
| 32 | + return lang | |
| 33 | +} | |
| 34 | + | |
| 35 | +export function loadLanguageAsync (lang = defaultLang) { | |
| 36 | + return new Promise(resolve => { | |
| 37 | + if (i18n.locale !== lang) { | |
| 38 | + if (!loadedLanguages.includes(lang)) { | |
| 39 | + return import(/* webpackChunkName: "lang-[request]" */ `./lang/${lang}`).then(msg => { | |
| 40 | + i18n.setLocaleMessage(lang, msg.default) | |
| 41 | + loadedLanguages.push(lang) | |
| 42 | + return setI18nLanguage(lang) | |
| 43 | + }) | |
| 44 | + } | |
| 45 | + return resolve(setI18nLanguage(lang)) | |
| 46 | + } | |
| 47 | + return resolve(lang) | |
| 48 | + }) | |
| 49 | +} | ... | ... |
front-end/h5/src/locales/lang/en-US.js
0 → 100755
| 1 | +export default { | |
| 2 | + app: { | |
| 3 | + title: 'Luban H5' | |
| 4 | + }, | |
| 5 | + header: { | |
| 6 | + chineseDocument: '中文文档', | |
| 7 | + englishDocument: 'Document(En)', | |
| 8 | + chat: 'Discussion Group', // | |
| 9 | + logout: 'Logout' | |
| 10 | + }, | |
| 11 | + sidebar: { | |
| 12 | + myWorks: 'My Works', | |
| 13 | + dataCenter: 'Data Center', | |
| 14 | + basicData: 'Basic Data', | |
| 15 | + templateCenter: 'Templates', | |
| 16 | + freeTemplates: 'Templates List', | |
| 17 | + accountCenter: 'Account' | |
| 18 | + }, | |
| 19 | + workCard: { | |
| 20 | + description: 'Desc', | |
| 21 | + createTime: 'Time', | |
| 22 | + useNow: 'Use it Now', | |
| 23 | + preview: 'Preview', | |
| 24 | + edit: 'Edit', | |
| 25 | + createNewWork: 'Create New' | |
| 26 | + }, | |
| 27 | + basicData: { | |
| 28 | + viewData: 'View Data' | |
| 29 | + } | |
| 30 | +} | ... | ... |
front-end/h5/src/locales/lang/zh-CN.js
0 → 100755
| 1 | +export default { | |
| 2 | + header: { | |
| 3 | + chineseDocument: '中文文档', | |
| 4 | + englishDocument: '英文文档', | |
| 5 | + chat: '交流群', // Discussion Group | |
| 6 | + logout: '退出登录' | |
| 7 | + }, | |
| 8 | + sidebar: { | |
| 9 | + myWorks: '我的作品', | |
| 10 | + dataCenter: '数据中心', | |
| 11 | + basicData: '基础数据', | |
| 12 | + templateCenter: '模板中心', | |
| 13 | + freeTemplates: '模板列表', | |
| 14 | + accountCenter: '账号中心' | |
| 15 | + }, | |
| 16 | + workCard: { | |
| 17 | + description: '描述', | |
| 18 | + createTime: '时间', | |
| 19 | + useNow: '立即使用', | |
| 20 | + preview: '预览', | |
| 21 | + createNewWork: '创建新作品', | |
| 22 | + edit: '编辑' | |
| 23 | + }, | |
| 24 | + basicData: { | |
| 25 | + viewData: 'View Data' | |
| 26 | + } | |
| 27 | +} | ... | ... |
front-end/h5/src/main.js
| ... | ... | @@ -2,6 +2,7 @@ import Vue from 'vue' |
| 2 | 2 | import App from './App.vue' |
| 3 | 3 | import router from './router' |
| 4 | 4 | import store from './store/' |
| 5 | +import i18n from './locales' | |
| 5 | 6 | // import './registerServiceWorker' |
| 6 | 7 | // import ElementUI from 'element-ui' |
| 7 | 8 | import Antd from 'ant-design-vue' |
| ... | ... | @@ -18,5 +19,6 @@ Vue.use(Antd) |
| 18 | 19 | new Vue({ |
| 19 | 20 | router, |
| 20 | 21 | store, |
| 22 | + i18n, | |
| 21 | 23 | render: h => h(App) |
| 22 | 24 | }).$mount('#app') | ... | ... |
front-end/h5/src/mixins/i18n.js
0 → 100755
front-end/h5/src/store/index.js
| ... | ... | @@ -5,6 +5,7 @@ import editor from './modules/editor' |
| 5 | 5 | import user from './modules/user' |
| 6 | 6 | import visible from './modules/visible' |
| 7 | 7 | import loading from './modules/loading' |
| 8 | +import i18n from './modules/i18n' | |
| 8 | 9 | |
| 9 | 10 | Vue.use(Vuex) |
| 10 | 11 | |
| ... | ... | @@ -22,7 +23,8 @@ export default new Vuex.Store({ |
| 22 | 23 | editor, |
| 23 | 24 | user, |
| 24 | 25 | visible, |
| 25 | - loading | |
| 26 | + loading, | |
| 27 | + i18n | |
| 26 | 28 | }, |
| 27 | 29 | plugins: [undoRedoPlugin] |
| 28 | 30 | }) | ... | ... |
front-end/h5/src/store/modules/i18n.js
0 → 100755
| 1 | +import { loadLanguageAsync } from '@/locales' | |
| 2 | + | |
| 3 | +const i18n = { | |
| 4 | + namespaced: true, | |
| 5 | + state: { | |
| 6 | + lang: 'zh-CN' | |
| 7 | + }, | |
| 8 | + mutations: { | |
| 9 | + SET_LANG: (state, lang) => { | |
| 10 | + state.lang = lang | |
| 11 | + } | |
| 12 | + }, | |
| 13 | + actions: { | |
| 14 | + // 设置界面语言 | |
| 15 | + SetLang ({ commit }, lang) { | |
| 16 | + return new Promise(resolve => { | |
| 17 | + commit('SET_LANG', lang) | |
| 18 | + loadLanguageAsync(lang) | |
| 19 | + resolve() | |
| 20 | + }) | |
| 21 | + } | |
| 22 | + } | |
| 23 | +} | |
| 24 | + | |
| 25 | +export default i18n | ... | ... |
front-end/h5/yarn.lock
| ... | ... | @@ -10885,6 +10885,11 @@ vue-hot-reload-api@^2.3.0: |
| 10885 | 10885 | resolved "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.3.tgz#2756f46cb3258054c5f4723de8ae7e87302a1ccf" |
| 10886 | 10886 | integrity sha1-J1b0bLMlgFTF9HI96K5+hzAqHM8= |
| 10887 | 10887 | |
| 10888 | +vue-i18n@^8.14.1: | |
| 10889 | + version "8.14.1" | |
| 10890 | + resolved "https://registry.npm.taobao.org/vue-i18n/download/vue-i18n-8.14.1.tgz#0ca0a2742c14e0144481655157fffcc7cc313e50" | |
| 10891 | + integrity sha1-DKCidCwU4BREgWVRV//8x8wxPlA= | |
| 10892 | + | |
| 10888 | 10893 | vue-jest@^3.0.4: |
| 10889 | 10894 | version "3.0.4" |
| 10890 | 10895 | resolved "https://registry.npm.taobao.org/vue-jest/download/vue-jest-3.0.4.tgz#b6a2b0d874968f26fa775ac901903fece531e08b" | ... | ... |