小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
上篇文章 <前端如何做国际化(上)> 主要讲了功能裁剪定制
连载阅读体验更佳
文案国际化
vue 的工程进行文案国际化,主要是使用 vue-i18n 插件进行国际化:vue-i18n 文档。
安装 vue-i18n:
npm i vue-i18n
之后,我们在 src 下创建 locale 文件夹,其目录结构如下:
├── locale
│ ├── district.js 获取保存上一节中通过webpack传入的国家配置
│ ├── index.js i18n主要的功能代码以及与elementUI(京东商家版)的设置
│ ├── langInterceptor.js 语言路由拦截器,用于控制懒加载哪一个语言包,以及设置显示语言
│ ├── langMap.js 语言映射表,用于对应各个语言的名称,用于语言切换的列表展示
│ ├── langs 存放语言的文件映射
│ │ ├── en_US.js 中文映射
│ │ └── zh_CN.js 英文映射
│ └── utils.js 国际化通用的功能
district.js
地区配置。
// 从webpack的环境变量中读取地区配置,格式为 { name: '', config: '' }
export const district = process.env.DISTRICT
// 通过key获取地区配置项
export const getDistrictConfig = key => {
return district.config[key]
}
// 取出语言列表项
export const languages = getDistrictConfig('languages')
// 取出cookie domain
export const cookieDomain = getDistrictConfig('cookieDomain')
// 不同地区的域名/url
export const urls = getDistrictConfig('urls')
// 不同地区的功能裁剪
export const functional = getDistrictConfig('functional')
export const passport = getDistrictConfig('passport')
lang/zh_CN.js
// 如果有引用组件库如 element-ui,则需要将组件库的对应的翻译文件引入
import zhCN from 'element-ui/lib/locale/lang/zh'
export default {
...zhCN,
locale: '语言',
title: '新宙斯 更能量',
...
}
这里的key随开发者自己定义。
index.js
/**
* VueI18n国际化配置
* */
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import zh_CN from '@/locale/lang/zh_CN'
import en_US from '@/locale/lang/en_US'
import th_TH from '@/locale/lang/th_TH'
// 如果有引入组件库如element-ui,则需要修改其翻译函数
import locale from 'element-ui/lib/locale'
const languageMsg = {
zh_CN,
en_US,
th_TH
}
const msg = {}
languages.forEach(lang => {
msg[lang] = languageMsg[lang]
})
Vue.use(VueI18n)
// 配置语言
const i18n = new VueI18n({
locale: languages[0], // 默认取第一个语言
messages: msg
})
locale.i18n((key, value) => i18n.t(key, value))
export default i18n
langMap.js
用于映射语言选择列表,切换语言选择项文案应该与其语言保持一致
export default {
zh_CN: '简体中文',
en_US: 'English',
}
utils.js
国际化工具类函数。
/**
* VueI18n 国际化语言配置
*/
/* eslint-disable */
import Cookies from '@/utils/js-cookie'
import i18n from './i18n'
import axios from 'axios'
import { cookieDomain } from './district'
/**
* 根据语言重定向 Url,此函数可用于切换语言
* @param {String} lang 语言标识
*/
export function setLocaleUrl(lang) {
Cookies.set('language', lang, {
domain: cookieDomain,
expires: 1
})
let href = location.href.replace(/language=([^&]*)/, `language=${lang}`)
location.href = href
}
/**
* 设置语言
* @param {String} lang 语言标识
*/
function setLocale(lang) {
i18n.locale = lang
// 修改ajax请求头,如果你是其他http包,则对应做修改
axios.defaults.headers.common['Accept-Language'] = lang
// 修改页面标题
document.title = i18n.t('title')
return lang
}
langInterceptor.js
语言路由拦截器,在进入页面之前,获取语言,并设置语言。
/**
* 语言 统一路由拦截
*/
import Cookies from '@/utils/js-cookie'
import { languages } from './district'
let LangInterceptor = {}
LangInterceptor.install = (Vue) => {
Vue.mixin({
beforeRouteEnter (to, from, next) {
let currentLanguage = ''
// languages指的是当前地区使用的语言列表
// Cookies指的是操作cookies的方法
// 先从 query 中取语言标识,并判断是否属于语言列表中的语言
if (to.query.language && languages.indexOf(to.query.language) > -1) {
currentLanguage = to.query.language
}
// 如果 query 中没有语言标识,则从 cookie 中获取,如果 cookie 中也没有,则取默认语言
if (!currentLanguage) {
let cookieLang = Cookies.get('language')
if (cookieLang && languages.indexOf(cookieLang) > -1) {
currentLanguage = cookieLang
} else {
currentLanguage = languages[0]
}
}
next()
}
})
}
export default LangInterceptor
之后在项目的入口文件 main.js 中,使用 LangInterceptor :
main.js
import Vue from 'vue'
import App from './App.vue'
import i18n from './locale/index'
import LangInterceptor from './locale/langInterceptor'
Vue.config.productionTip = false
Vue.use(LangInterceptor)
new Vue({
i18n,
render: h => h(App)
}).$mount('#app')
之后是在项目中对需要翻译的文案进行翻译:
<div id="app">
<p>{{ $t('title') }}</p>
</div>
中英文切换的业务代码示例:
<template>
<!-- 这里使用的是 element-ui -->
<el-dropdown @command="handleCommand">
<span class="el-dropdown-link">
{{langMap[$i18n.locale]}}
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="(lang, index) in languages"
:key="index"
:command="lang"
>{{ langMap[lang] }}</el-dropdown-item>
</el-dropdown-menu>
</template>
<script>
import langMap from "@/locale/langMap"
import { setLocaleUrl } from "@/locale/utils"
import { languages } from "@/locale/district"
export default {
name: "Header",
data() {
return {
langMap,
languages
}
},
methods: {
handleCommand(command) {
setLocaleUrl(command);
}
}
};
</script>
再回到功能裁剪
功能裁剪一般需要裁剪功能入口以及对应的页面路由。
裁剪入口:
<template>
<header class="header">
<router-link v-if="functional.vapp" to="/vapp">小程序</router-link>
</header>
</template>
<script>
import { functional } from '@/locale/district'
export default {
data () {
return {
functional
}
}
}
</script>
裁剪路由:
router.js
import Vue from 'vue'
import Router from 'vue-router'
import { functional } from '@/locale/district'
import Index from '@/views/index.vue'
const router = new Router({
routes: [
{
path: '/',
component: Index
},
// 裁剪 vapp 页面
...(functional.vapp ? [{
path: '/vapp',
component: () => import('@/views/vapp.vue')
} : [])
]
})
index.html 中怎么获取变量使用的配置
index.html 文件是 html-webpack-plugin 插件处理的,该插件从 3.0 开始,是支持向 html 中传入配置的。
vue-cli3 开始,自动将 vue.config.js 的配置传入了 index.html 中
html-webpack-plugin 通过添加 templateParameters 函数,自定义传入的数据。
const localeConfig = require('path/to/locale')
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
templateParameters: (compilation, assets, pluginOptions) => {
let stats
return {
get webpack () {
return stats || (stats = compilation.getStats().toJson())
},
compilation: compilation,
webpackConfig: {
...compilation.options
},
htmlWebpackPlugin: {
files: assets,
options: pluginOptions
},
config: {
stream: localeConfig.config.stream
}
}
}
})
vue-cli 2 创建的项目需要升级下 html-webpack-plugin,手动执行 npm i html-webpack-plugin@3 -D
上篇文章 <前端如何做国际化(上)> 主要讲了功能裁剪定制
连载阅读体验更佳
点赞支持、手留余香、与有荣焉,动动你发财的小手哟,感谢各位大佬能留下您的足迹。
往期精彩推荐
Vue 虚拟 DOM 搞不懂?这篇文章帮你彻底搞定虚拟 DOM
Git 相关推荐
面试相关推荐
更多精彩详见:个人主页