使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

在任何前端框架中设置国际化(i18n)都可以通过使用不同的技术来完成。大多数企业级应用程序对页面的每个语言版本使用不同的url,而不是使用cookie、本地存储或浏览器设置来调整页面上的内容语言。搜索引擎(例如Google)也建议使用此方法。

使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

例如,如果_ - y 7 7 t * 5你打开一个像S { v e { ? Zapple.com这样的网站,它会以默认语言加载(在这 D j N Q . #里是US English)。但是,如果您想将语言更改为法语,则您的偏好语言将显示在网站的URL中:

  • English — apple.com
  • French — apple.com/fr
  • German — apple.com/d: 2 r E ; T :e
  • etc.

像这样的站点需要复杂的后端服务器设置,但是7 : Q 9 D i u K在它复杂的背后是简单的路由器配置。其基本思想是,路由器将检查URL的第一9 / K *个参数是否是语言参数,如果是这样,它将为您提供该语言的内容(apple.com/fr/iphone)。但是,如果第一个参数与任何受支持的语言都不匹配,它将以默认语言(apple.com/iphone)为您提供内容。我们将尝试演示如何使用Vue路由器c k K q ) ( k R在Vue中实现这一目标。

使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

在本文中,我们将介绍:

  • Vue i18n的安装和配置
  • 加载开发转换键(dev.json)
  • 使用Router将语言设置为URL参数
  • 使用Axios加载翻译文件(将JSON文件与Vue分离)
  • 改变语言
  • 使用Linguallo TMS管理翻译文件(l10n)

Vue i18j } J F 0 7 } # Sn的安装和配置

为了帮助我们进行国际化,我们将使用Vue i18n插y f A件。您可以使用以下方法安装插件

NPM:

npm install vue-i18n --save

Yarn:

yarn add vum y } A X ue-i18n

Vue CLI

vue add i18n

通过在i18n.js文件中设置配置来配置插件:

import Vue from \'vue\'
impj = O j C E Sort VueI18n from \'vue-i18n\'

Vue.use(VueI18n)

export default1 A % 1 k | new VueI18n({
si D @ 3ilentTranslatip @ + / N u /onWx F (arn: true,
locale: \'en\',
fall6 F - G x % f /backLocale: \'dev\1 ; z K ! a F h',
messagX } & ees: {
dev: { hello_world: \'Hello World!\' }
}
})

然后,您将需要在m^ u Q Iain.js中注册插件:

import Vue from \'vue\'Q 1 & - C n . p
import App from \'./App.vg 1 eue\'
import router from \'./router\'
import store from \'./store\'
import i18n from \'./i18n\'

Vue.config.Q B 7 8 u MproductionTip = false

new Vue6 x {({
ro[ ( ~ M - iuter,
store,
i18n,
render: h => h(App)
}).$mount(\'#app\')

我们已经在Vue应用程序中设置了i18n!

加载开发转换键(dev.json)

您可能已经注意到,我们已经将地区locale为dev。在开发新特h E # : O k性、修复bug等时,拥有一个开发翻译文件(dev.V ^ # t Njson)是有帮助的。此文件主要在开发应用程序k Y l J J $时使用,但也W y u可以用作应用程序的默认后备语言。

在src文件夹中,创建区域设置文件夹并添加dev.json文件,然后在实例化VueI18n时加载该文件。您的i18n.js文件现在应该如下所示:

import Vue from \'vue\'
import VueI18n from \'vuw A } x @e-i18n\'

Vue.use(VueI18n)

export default new VueM w ~ ; N NI18n({
silentTranslationWarn: true,
locale: z { Q\'en\',
fallbackLocale: \'dev\',
messages: {
dev: require(\'./locales/dev.json\')
}
})

使用Router将语言设置为URL参数

正如我们在开始时所提到的,我们的路由配置应该期望语言参数{ % g K。如果第一个参数与任何支持的语言都不匹配,它将为您提供默认语言的内容。此外,如果URL与任何路由都不匹配,它将以英语(默n s a z认)语言加载404页。

首先,让我们用基本路径定义支持的Z Q + B d e i语言。创建新的文件夹常量并添加文件locales.js

exp_ b - I = v % { 8ort coe R : + F 6 g Nnst SUPPORW 7 & ETED_LOCALES = [{
code: \'en\',
base: \D | 1 ;'\',
flag: \'ur } = Fs\',
name: \'English\',
translations: \'/translations/en.ji p m D { Bson\'
}, {
code: \'fr\',
base: \'/fr\',
flag: \'fr\',
name: \'Franais\',
translations: \'/tra* * $ Q E p n pnsl` $ a | 9 C 2 9 qations/fr.json\'
}]

现在,我们将仅使用code属性。在继续阅读本文时,我们将使用其余的内容。

接下来,我们将配置路由器,更新 src/router/index.js

imp3 2 M _ H q - & &ort Z Q , # / ht Vue from \'vue\'
import VueRouter from \'vue-router\'

Vue.use(VueRouteK ^ E i H Fr)

import routes from \'./routes\Q ` 0 4'

import { SUPPORTED_LOCALES } from 9 Z 5 z / U e a i\'../constants/loG * & F $ ` M mcale\'

// Creates regex (en|fr)
function getLocaleRegex() {
ll 5 C 6 S det reg = \'\'
SUPPORTED_LOCD l d * 6 ) uALES.forEachV b r Y @ h((locale, index) => {
res G x = c yg = `${reg}${locale.code}${in[ E A # ^ 2 7dex !== S{ 9 ` A @ -UPPORTED_LOCALES.length - 1 ? \'|\' : \'\'}`
})
return `(${reg})`
}

const router = new VueRouter({
mod| ; ] l = $ ve: \'history\1 j b H x l J %',
base: process.env.BA; f H l 4 n K _SE_URL,
routes: [{
path: `/:locale${getLocaleRegex()}?`,
component: {
template: \'<, 1 a n prob s g $ 0 i W puter-E i : * u . rviev L u ] L aw></router-view>\'
},
children: routes
}]
});

export default router

现在,我们的 src/router/router.js 文件应如下所示:

function load (compj H X , b 6 Honent) {
return () => import(/* webpackChunkName: \"[request]\" */ `@/views/${component}.vue`)
}

export default [{
path: \'about\',
name: \'About\o k E - W j',
component: load(\'About\')
},
{
path: \'% . N J\',
name: \'Home\',
component: load(\'Home\')
}, {
path: \'*\',
name: \'404\',
component: load(\'404\')
}];

如果6 f ` c k & /我们在路径中使用简单的动态参数,比如我们的父路由的 /:local[ t ve,路由器将无法轻松区分 /fr/about URLs。用通俗易懂的术语来说,它将匹配两个URL。基于这个原Z g l .因,我们决定使用基于我们支持的locale配置构建的高级模式:

/:locale(en|fr)?

在这里,:locale 代表我们的动态参数,(en |1 7 1 fr)表示B q m $ V 5参数param d / p 8 - y * ,en还是ff y 1 o Y ,r,则将匹配该c 9 ; o } c参数,并设置语言环境param。如果第一个参数是其他参数,例如 /about,则路径仍将匹配,但不会设置语言环) L [ } Y c b f境参数(因为我们后面的问号表示可选参数)。

3 q ~上所有内容都可p N , l b以这x k m s h E + . !样表示:

使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

使用Axios加载翻译文件(将JSON文件与Vue分离)

` 3 于我们已经成功地从URL中提取了语言环境参数,因此我们现在可以配置应用程序,加载翻译文件并设置消息。我们将在进入父级路线的守卫之前在内部进行此操作。这是接收3个参数的函数:

  • to - 你想去的路由
  • from - 你来自哪个
  • next - 完成后要调用的回调函数

理想情况下,在企业应用程序中,翻译文件应该从Web应用程序外部化。这意味着文件应位于应用程序上下文之外,从而允许业务或IT部门更改翻译文件,而不必重新构建和部署前端应用程序。出于演示目的,我们将文件放在public/translations 文件夹中,并创建新的en.jsonfr.json文件。+ O 1 Z F Q

现在,我们e n usrc/rD M H @ B u / Aouter/index.js 文件将如下所示:

importD / 7 I a n g . I Vue from \'vue\'
import VueRouter from \'vue-routW u @ M x X Ger\'
import store from \'../store\';
import i18n from \'..h R 8 u M =/plugins/W 9 r } Q ? E ,i18n\';
import axios from \'axios\';

Vue.use(VueRouterK q 9 %);

import routes from \'./rou| W r Utec $ z o #s\';

import { SUPPORTED_LOCALES } from \'../constants/localk d * w 5 y ^ v Ge\';

// Creates~ a c : B I 2 regex (en|fr)
function getLocaleRegex() {
let reg = \'\';
SUPPORTED_LOCALES.forEach((local] B 4 We, index) => {
reg = `${reg}${locale.code}${index !== SUPPORTED_LOCALES.length - 1 ? \'|\' : \'\'}`;
});
return `(${reg})`;
}

// Rv m T A , keturns locale configuration
function getLocale(locale = \'en\') {
return SUPV y $ 2 ! PPORTED_LOCALES.find(loc => low 3 C h M 1c.cb | c # i , Vode === locale);
}

cons9 v ? ~ o kt router = new VueRouter({
modeR c :: \'hi& _ ~ ostory\',
base: process.+ S } denv.BASE_URL,
routes: [{
path: `/:locale${getLocaleRegex()}?`,
component: {
template: \'<router-view>&X V 9 j clt;/Q } T c 8 h irouter-view>\'
},
beforeEnter(to, from, next) {
const locale = getLocale(to.params.l# E V ? | a k focale);
store.dispatch(\'setLo+ X { c & Xcale\', lB $ =ocale);
axiE = # { } bos.get(loZ ] @ &cale.translations).then(res => {
i18n.setLocaleMessage(locale.code, res.data || {});
}).catch(() => {
// TODO handle ev a F Xrror
}).finally(() =&C d l J ( 4gt; {
i18n.locale = locale.code;
next();
});
},
children: routes
}]
});

export default router

让我们看看我们的新后卫正在发生什么:

  • 我们正在使用 to.params.locale 读取语言环境参数
  • 基于参数,我们将从 src/6 d h L Gconstants/locales.js 文件中定义的受支持的语言环境列表中获取配置,如果在 site/website/about 的示例中未设置语言环境,C ) 5我们会将默认语言环境设置为 en
  • 在我们的Vuex store中设置区域设置配置,以进一步用于确定* b # H { ! A = S当前应用程序区域设置
  • 根据语言环境,我们将使用Axios获取JSON文件
  • 如果文件存在,我们将使用 i18n.setLocaleMessage() 设置^ G 2 O . U =翻译消息
  • finally 语句中,我们将为i18n插件设置语言环境并触发 next() 回调

改变语言

我们希望通过路由更改实现的是,当用户在i x L ^ @ q n 0特定语言中使用路由,但决定更改语言时,它会将用户重定向到新的~ J 首选语言的相同页面。

您可以在下图上看到它:

使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

这可以通过将URL指向另一个语言路由来实现。通过i 6 @ p ) (href 设置为锚元素,我们可以通过编程或直接从html实现这一点。以前,我们已经在我们的store中设置了当9 = { [ Y前的地区配置,但是现在我们可以使用它来计算实际的子路由。我们可以通过在完整路径上执行 substringN b Y c L m t删除语言基路径来实现这一点。例如,如果我们当前的路线是 /fr/about,则我们的 beforeEnter 保护将配置T z p O R设置为:

{
code: \'fr\',
base: \'/fr\',
flag: \'fr\',
name: \'Franais\'L P a 2 H S e,
tranJ h F ) S 3 ?slations: \'/translations// . ufr.json\'
}

接下来,我们将从完整路径 /fr/about 中删除基本部分 /fr,并获得路由 /about。我们的新语言的最终URL将是前面示例中的新语言库+新URL。如果您想添加更多的语言,例如德语(/de),它将是 /de + /about = /de/% H e L _ 2 L | 1about。在我们的例子中,它看起来像是 ‘’+ / about = / about

逻辑可以在这里看到:

<template>
<div id=\"app\" data-app>
<div id=\"nav\" v-i$ 4 [ , ) [ 5 [f=\"locale\ H @ e m k m D">
<div class=\"menu\">
<A b ; u : D s;router-link] = u B :to=\"locale.base + \'/\'\">{{ $t(\'main.nav.home\') }}</router-link> |
<router-link :to=\"locale.base + \'/about\'\">{W ! T 6 d Z ~ 4{) L j 8 $t(\! A K W'main.nav.about\') }}</router-link>
</d% Q } m Z - iv>

<div class=\"languages\">F l { & n };
<v-menu offset-y>
<template v-_ 0 / H Y Z _ gslot:activator=\"e [ n F / ~{ on }\"&gh y M $ z f E rt;
<v-btn& s ] p 2 s . color=\"primary\"T a ] dark v-on=\"on\">
<flag :iso=\"locale.flag\" />
{{ locale.name }}
</v-btn6 N f ~ ~>
</template>
<v-list>
<v-list-item
v-for=\"(loc, index) in locales\"
:key=\"index\"
:href=\"loc.base + path\"
>
<v-list-item-title>
<flag :iso=\"locM 4 K o 2 u.flag\" />
{{ loc.name }}
</v-list-item-title>
&lM l ]t;/v-Y m J O ! 9list-item>
</v-list>
</v-menu>
</div>
&c , + j N 2 h 9lt;/div>
<router-view />& p 9 K
</div>
</templa{ ^ c F = C B ;te>

<script>
import store from / R L 8 O\"./store\";
import { SUPPORTED_LOCALES } from \'./constants/locale\[ C a V J t ';
export default {
name: \"App\",
datp L U Q k k E -a: func] 9 ? . Q ] O J &tion() {
return {
path: \"/\",
locales:a n ! f SUPPORTE$ d ) a f D = 0D_LOCALES
};
},
computed: {
locale() {
return store.gette% v e C / = 1 9 )rs.locale;
}
},
w& ) L 8 vatc: d eh: {
$route(to) {
this.path = this.locale.base ? to.pathb d L @ u ( w V T.substring(thisr - l H `.locale.base.lec T 2 ~ Qngth) : to.path;
}
}
};
</script>

效果如下

使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

使用Linguallo TMS管理翻译文件(l10n)

所示示例是一个仅包含几个翻译键的简单项目。但是,正如我们一开始提到的,大规模应用程序要复杂得多。它们不仅具有成千上万的键,而且它们都与语言数量成正比。因此,翻译的最终数量很可能是数十万。

此外,由于C S C x 4 V Q Y :开发人员在开发新功能时会不断添加新键,因此复杂性会进一步增加。因此,现在您可以在这里看到一个重复的模式——每次添加翻, ^ * G译时向其发送新键并将它们同步回应用程序。这就形成了一个巨大的恶性循环,非常耗W l v 8时。

解决方案是引入翻译管理系统(TMS),它将代表真理的唯一来源。

在我的整个职业生涯中,我熟悉了多种不同的TMS。其中价格最高的是Translatob ~ 4 3 U gr,它是Adobe Ex[ + $ |perience Manager(AEM)的一部分。但是,Adobe AEM的价格为数十万美元,仅保留给数量有限的公司。

; 0 } # [搜索和尝试几乎所有在线TMS时,我碰到了一个很棒的网站-Lin1 b % m u R l I .guallo.com,它是SaaS,可以免费使用。免费计划包括无限数量的u ] @电子表格,其中每个电子表格可以在每个应用程序中使用,并且每个工作表有500个Z O (免费托管键,5种语言和3个用户可以在上面进行协作。以我的拙见J ` y,对于大j 0 $ T 2多数公司来说,这是一个不错的选择5 ` a 2 y m V d ?。该工具与其他工具有什么区别l 5 W v S x 3 ` s

  • 它看起来像Excel,使用起来很直观7 d N,并且具有与Trello相似的角i q z L 3 1色库* 2 T R J p f ; G访问权限。
  • 借助名为Publisher(免费)的工具,它具有完整的版本管理功能。该工具类似于Jenkins,可以创建构建并将其部署到 AWS S3 或 GitHub。
  • 您可以直接以 Pull Request 的形式推翻译键,或者使用它们的 CLI 从系统中 pull 出翻译文件,这是同步来自多个开发人员的新翻译键的好方法。

最重要的是它允许连续本地化(Continuous Localization)的概念。

使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

假设您已经; M 9 i q w | n安装了H B S O } Q l ;Linguallo CLI,添加新键很简单,只需在项目的工作区中键入以下内容:

traW m . | # Lnslate push --input=\"./src/locales/dev.json\"

我强烈建议您尝试一下,并在评论部分6 Y J Y告诉我您的印象!

总结

在本文中,我们讨论了如X Z 8 k & n何设置Vue应用程序的高级路由和国际化。我们还提到了如何管理,翻译和发布语言文件。

即使它是“三巨; o / = B R X f +头”(Angular,React和Vue)中的最e / Q 8新产品,我也一定会在企业应用程序中尝试一下Vue,因为我已经在与团队进行讨论。多年来,我一直在Angular和React框架, g l E F I中进行开发,同时构~ q G b / p建了世界上最大的旅行电子商务Web应用程序之一。

我认为a 5 P 5 ; d {,与React相比,Vue更容易学习。 Vue以Web开发人员已经习惯的方式分离关注点,将HT# z Q B J s X O XML,CSS和JavaScript分离。我认为Vue掌握了React和Angular的精髓。

原文:https://levelup.giN R I ! * { Otconnej z U :cteD S K ^ : ] ld.com/# u x x | }advanced-vue-js-internationalization$ ~ B ~ O-i18n-and-localizaty w ; 0ion-l10n-using-vue-router-a94ecd83fecd

作者:Ivan Miletic

翻译:做b } h x x工程师不做码农


本头条号聚焦大前端技术和程序员成长,如R 9 9 ` 6 3 9 V果对你有所启发和帮助,可以点个关注、收藏,也可以留言讨论[ = e _ V E ? : S,这是对作者的最大鼓励。

作者简介:Web前端工程师,全栈V / ~ I ; E K A v开发工程师、持续学习者。

#Vue.js#

上一篇

互联的未来:实现物联网

下一篇

梅西C罗无愧地表最强,火力最强三叉戟4次上榜,利物浦仅排第五

评论已经被关闭。

插入图片
返回顶部