Skip to content

Commit

Permalink
feat(i18n): 主要增加了国际化方案
Browse files Browse the repository at this point in the history
同时增加国际化切换语言的组件以及通用样式,调整格式
  • Loading branch information
白唯 committed Sep 29, 2020
1 parent 1f9c248 commit 7affdf8
Show file tree
Hide file tree
Showing 15 changed files with 662 additions and 30 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
"email": "[email protected]",
"url": "http://me.ibwei.com"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
Expand All @@ -28,12 +25,15 @@
"@types"
],
"dependencies": {
"ant-design-vue": "^2.0.0-beta.6",
"@vue/composition-api": "^1.0.0-beta.14",
"@vueuse/core": "^4.0.0-beta.16",
"ant-design-vue": "^2.0.0-beta.9",
"axios": "^0.20.0",
"core-js": "^3.6.5",
"moment": "^2.27.0",
"vue": "^3.0.0-0",
"vue-class-component": "^8.0.0-0",
"vue-composable": "^1.0.0-beta.10",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0",
"vuex-persistedstate": "^3.1.0"
Expand Down
77 changes: 77 additions & 0 deletions src/components/ChangeLanguage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<template>
<a-dropdown :trigger="['click']">
<a class="ant-dropdown-link" @click="e => e.preventDefault()" :style="{ color: titleColor, fontSize: titleSize }"> {{ i18n.languageName }}<DownOutlined /></a>
<template v-slot:overlay>
<a-menu class="dropdown-panel">
<a-menu-item v-for="(value, key) of LanguageNameList" :key="key" @click="changeLanguage">
<span :style="{ color: textColor }">{{ LanguageNameList[key] }}</span>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>

<script>
import { defineComponent } from 'vue'
import { setLang, i18nInstance, LanguageNameList } from '../i18n/index'
import { message } from 'ant-design-vue'
import { DownOutlined } from '@ant-design/icons-vue'

export default defineComponent({
props: {
titleColor: {
type: String,
default: '#fff'
},
textColor: {
type: String,
default: '#fff'
},
titleSize: {
type: String,
default: '16px'
}
},
components: {
DownOutlined
},
setup() {
const { i18n } = i18nInstance
const changeLanguage = e => {
const lang = e.key
setLang(lang).then(result => {
if (result === lang) {
message.success(`${i18n.value['Current Language:']} ${i18n.value.languageName}`)
}
})
}
return {
LanguageNameList,
changeLanguage,
i18n
}
}
})
</script>

<style lang="less" scoped>
.dropdown-panel {
background: rgba(255, 255, 255, 0.3);
margin-top: 10px;
/deep/ .ant-dropdown-menu-item-active {
background: transparent;
transform: translateX(2px);
transition: all 0.2s ease-in-out;
}
}
.dropdown-panel::before {
content: '';
display: block;
border: 10px solid transparent;
border-bottom-color: rgba(255, 255, 255, 0.3);
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
}
</style>
97 changes: 97 additions & 0 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* vue-i18n 使用姿势说明
* see more : https://pikax.me/vue-composable/composable/i18n/i18n.html#parameters
*/

import { includes } from 'lodash'
import Store from '@/store'
import moment from 'moment'
import { findKeyByValue } from '@/utils/common'
import { useI18n } from 'vue-composable'
import zhCN from '@/i18n/messages/zhCN'
import en from '@/i18n/messages/en'

let __LOCALE__ = Store.__s('app.language')

if (!__LOCALE__) {
__LOCALE__ = window.navigator.language.split('-').join('')
Store.__s('app.language', __LOCALE__)
}

/** 定义语言模版 */
export const Locales: any = {}

/**
* @todo 语言名字命名要考虑三个部分:一是 antdv 组件国际化的语言名字,二是 i18n模版语言的命名,三是浏览器对于语言的命名(这里会跟 http 请* 求相关,也是后端能识别的语言命名),因此要将前两种语言的名字通过字典转换成标准名称,也就是浏览器的语言名使用SO 639-1标准
*/

export const TranslateTable: { [key: string]: string } = {
en: 'en_US',
zhCN: 'zh_CN'
}

export const LanguageNameList: { [key: string]: string } = {
en: 'English',
zhCN: '简体(中文)'
}

export const i18nInstance = useI18n({
locale: 'zhCN',
messages: {
zhCN,
en
}
})

/**
* @description 自动加载 antd-vue 需要的语言模版
*/
function loadAtdLocales() {
const files = require.context(
'../../node_modules/ant-design-vue/es/locale-provider',
true,
/\.js$/
)
files.keys().forEach(key => {
const fileName = /(?<=\/)\S+(?=\.)/.exec(key) as Array<any>
if (includes(TranslateTable, fileName[0])) {
const localeKey = findKeyByValue(TranslateTable, fileName[0])
if (localeKey) {
Locales[localeKey] = files(key).default
}
}
})
}

/**
* @functin setLang - set the app's language
* @param {string} lang - the language will be setted
* @return {string} lang - langguage name
*/

function _set(lang: keyof typeof TranslateTable): any {
i18nInstance.locale.value = lang as any
// 设置当前语言的时间
moment.locale(TranslateTable[lang])
// Axios.defaults.headers.common['Accept-Language'] = lang
Store.__s('app.language', lang)
return lang
}

/**
* @functin 异步加载自定义的 i18n 模版
* @param {string} lang - 将要更换的语言
* @return {string} lang - 返回将要更改的语言明后才能
*/
export function setLang(lang: string): Promise<string> {
if (lang === i18nInstance.locale.value) {
return Promise.resolve('same')
}
return Promise.resolve(_set(lang))
}

/* 加载 antd 模版 */
loadAtdLocales()

/** 设置初始化语言 */
setLang(__LOCALE__)
6 changes: 6 additions & 0 deletions src/i18n/messages/en.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
languageName: 'English',
'Current Language:': 'Current Language:',
cancel: 'cancel',
Play: 'Play'
}
9 changes: 9 additions & 0 deletions src/i18n/messages/zhCN.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const zhCN = {
languageName: '中文(简体)',
'Current Language:': '已经成功切换到',
cancel: '取消',
Play: '点击播放视频'
}
type i18nType = typeof zhCN
export default zhCN
export { i18nType }
5 changes: 4 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ loadAllPlugins(app)
/** 自动注册全局组件 */
registeGlobalComponent(app)

app.use(store).use(router).mount('#app')
app
.use(store)
.use(router)
.mount('#app')
15 changes: 12 additions & 3 deletions src/plugins/antd.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { Button, Card, Row, Col, Tag, Form, Input } from 'ant-design-vue'
import { createApp } from 'vue'
import { Button, Card, Row, Col, Tag, Form, Input, ConfigProvider, Select, DatePicker, Dropdown, Menu, Divider, Badge, BackTop, Carousel } from 'ant-design-vue'
import '@/styles/antd.less'

/**
* @description 手动注册 antd-vue 组件,达到按需加载目的
* @description Automatically register components under Button, such as Button.Group
* @param {ReturnType<typeof createApp>} app 整个应用的实例
* @returns void
*/
export default function loadComponent(app: ReturnType<typeof createApp>) {
export default function loadComponent(app: any) {
app.use(Button)
app.use(Card)
app.use(Row)
app.use(Col)
app.use(Tag)
app.use(Form)
app.use(Input)
app.use(Dropdown)
app.use(Menu)
app.use(Divider)
app.use(ConfigProvider)
app.use(Select)
app.use(DatePicker)
app.use(BackTop)
app.use(Badge)
app.use(Carousel)
}
2 changes: 1 addition & 1 deletion src/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { createApp } from 'vue'
*/
export function loadAllPlugins(app: ReturnType<typeof createApp>) {
const files = require.context('.', true, /\.ts$/)
files.keys().forEach((key) => {
files.keys().forEach(key => {
if (key !== './index.ts') files(key).default(app)
})
}
18 changes: 18 additions & 0 deletions src/styles/antd.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 配置 antd 样式相关
@import '~ant-design-vue/dist/antd.less'; // 引入官方提供的 less 样式入口文件

// 定制主题
@primary-color : #00a971; // 全局主色
@primary : #00a971;
@link-color : #00a971; // 链接色
@success-color : #52c41a; // 成功色
@warning-color : #faad14; // 警告色
@error-color : #f5222d; // 错误色
@font-size-base : 14px; // 主字号
@heading-color : rgba(0, 0, 0, 0.85); // 标题色
@text-color : rgba(0, 0, 0, 0.65); // 主文本色
@text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色
@disabled-color : rgba(0, 0, 0, 0.25); // 失效色
@border-radius-base : 2px; // 组件/浮层圆角
@border-color-base : #d9d9d9; // 边框色
@box-shadow-base : 0 2px 8px rgba(0, 0, 0, 0.15); //
37 changes: 37 additions & 0 deletions src/styles/common.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.g-description,
.g-desc {
font-size : 18px;
font-weight: 400;
color : #333333;
line-height: 27px;
text-align : justify;
}

.g-title {
font-size : 36px;
font-weight: 500;
color : #333333;
line-height: 36px;

}

.g-sub-title {
font-size : 30px;
font-weight: 500;
color : #333333;
line-height: 30px;
}

.g-flex-row {
display : flex;
flex-flow : row nowrap;
justify-content: center;
align-items : center;
}

.g-flex-col {
display : flex;
flex-flow : column nowrap;
justify-content: center;
align-items : center;
}
21 changes: 21 additions & 0 deletions src/styles/iconfont.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* iconfont */
@font-face {
font-family: 'iconfont'; /* project id 2092412 */
src: url('//at.alicdn.com/t/font_2092412_vdxq6u8c7um.eot');
src: url('//at.alicdn.com/t/font_2092412_vdxq6u8c7um.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_2092412_vdxq6u8c7um.woff2') format('woff2'),
url('//at.alicdn.com/t/font_2092412_vdxq6u8c7um.woff') format('woff'),
url('//at.alicdn.com/t/font_2092412_vdxq6u8c7um.ttf') format('truetype'),
url('//at.alicdn.com/t/font_2092412_vdxq6u8c7um.svg#iconfont') format('svg');
}

.iconfont {
font-family: 'iconfont' !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}

/** 使用姿势 <i class="iconfont">&#x33; </i> */
4 changes: 4 additions & 0 deletions src/styles/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import './normalize.css';
@import './var.less';
@import './iconfont.less';
@import './common.less';
Loading

0 comments on commit 7affdf8

Please sign in to comment.