vue-router 路由嵌套显示不出来_使用Vue Router高级用法进行Vue.js国际化(i18n)和本地化(l10n)

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

96188ee1e2d5bff379dc0457e9ed363d.png

例如,如果你打开一个像apple.com这样的网站,它会以默认语言加载(在这里是US English)。但是,如果您想将语言更改为法语,则您的偏好语言将显示在网站的URL中:

  • English — apple.com
  • French — apple.com/fr
  • German — apple.com/de
  • etc.

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

082c21190f27e0c3ea32d176b5618c59.png

在本文中,我们将介绍:

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

Vue i18n的安装和配置

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

NPM:

npm install vue-i18n --save

Yarn:

yarn add vue-i18n

Vue CLI

vue add i18n

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

import Vue from 'vue'import VueI18n from 'vue-i18n'Vue.use(VueI18n)export default new VueI18n({  silentTranslationWarn: true,  locale: 'en',  fallbackLocale: 'dev',  messages: {    dev: { hello_world: 'Hello World!' }  }})

然后,您将需要在main.js中注册插件:

import Vue from 'vue'import App from './App.vue'import router from './router'import store from './store'import i18n from './i18n'Vue.config.productionTip = falsenew Vue({  router,  store,  i18n,  render: h => h(App)}).$mount('#app')

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

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

您可能已经注意到,我们已经将地区locale为dev。在开发新特性、修复bug等时,拥有一个开发翻译文件(dev.json)是有帮助的。此文件主要在开发应用程序时使用,但也可以用作应用程序的默认后备语言。

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

import Vue from 'vue'import VueI18n from 'vue-i18n'Vue.use(VueI18n)export default new VueI18n({  silentTranslationWarn: true,  locale: 'en',  fallbackLocale: 'dev',  messages: {    dev: require('./locales/dev.json')  }})

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

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

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

export const SUPPORTED_LOCALES = [{  code: 'en',  base: '',  flag: 'us',  name: 'English',  translations: '/translations/en.json'}, {  code: 'fr',  base: '/fr',  flag: 'fr',  name: 'Français',  translations: '/translations/fr.json'}]

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

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

import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter)import routes from './routes'import { SUPPORTED_LOCALES } from '../constants/locale'// Creates regex (en|fr)function getLocaleRegex() {  let reg = ''  SUPPORTED_LOCALES.forEach((locale, index) => {    reg = `${reg}${locale.code}${index !== SUPPORTED_LOCALES.length - 1 ? '|' : ''}`  })  return `(${reg})`}const router = new VueRouter({  mode: 'history',  base: process.env.BASE_URL,  routes: [{    path: `/:locale${getLocaleRegex()}?`,    component: {      template: ''    },    children: routes  }]});export default router

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

function load (component) {  return () => import(/* webpackChunkName: "[request]" */ `@/views/${component}.vue`)}export default [{  path: 'about',  name: 'About',  component: load('About')},{  path: '',  name: 'Home',  component: load('Home')}, {  path: '*',  name: '404',  component: load('404')}];

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

/:locale(en|fr)?

在这里,:locale 代表我们的动态参数,(en | fr)表示参数param是en还是fr,则将匹配该参数,并设置语言环境param。如果第一个参数是其他参数,例如 /about,则路径仍将匹配,但不会设置语言环境参数(因为我们后面的问号表示可选参数)。

以上所有内容都可以这样表示:

5aa74e4c5b02ce405c0b34faa773c285.png

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

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

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

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

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

import Vue from 'vue'import VueRouter from 'vue-router'import store from '../store';import i18n from '../plugins/i18n';import axios from 'axios';Vue.use(VueRouter);import routes from './routes';import { SUPPORTED_LOCALES } from '../constants/locale';// Creates regex (en|fr)function getLocaleRegex() {  let reg = '';  SUPPORTED_LOCALES.forEach((locale, index) => {    reg = `${reg}${locale.code}${index !== SUPPORTED_LOCALES.length - 1 ? '|' : ''}`;  });  return `(${reg})`;}// Returns locale configurationfunction getLocale(locale = 'en') {  return SUPPORTED_LOCALES.find(loc => loc.code === locale);}const router = new VueRouter({  mode: 'history',  base: process.env.BASE_URL,  routes: [{    path: `/:locale${getLocaleRegex()}?`,    component: {      template: ''    },    beforeEnter(to, from, next) {      const locale = getLocale(to.params.locale);      store.dispatch('setLocale', locale);      axios.get(locale.translations).then(res => {        i18n.setLocaleMessage(locale.code, res.data || {});      }).catch(() => {        // TODO handle error      }).finally(() => {        i18n.locale = locale.code;        next();      });    },    children: routes  }]});export default router

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

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

改变语言

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

您可以在下图上看到它:

a8dfc63c1893ffa2722e5a713dfd8bca.png

这可以通过将URL指向另一个语言路由来实现。通过将 href 设置为锚元素,我们可以通过编程或直接从html实现这一点。以前,我们已经在我们的store中设置了当前的地区配置,但是现在我们可以使用它来计算实际的子路由。我们可以通过在完整路径上执行 substring 并删除语言基路径来实现这一点。例如,如果我们当前的路线是 /fr/about,则我们的 beforeEnter 保护将配置设置为:

{  code: 'fr',  base: '/fr',  flag: 'fr',  name: 'Français',  translations: '/translations/fr.json'}

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

逻辑可以在这里看到:

效果如下

489ff7442a84a5aa6a4c3929997e3537.gif

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

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

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

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

在我的整个职业生涯中,我熟悉了多种不同的TMS。其中价格最高的是Translator,它是Adobe Experience Manager(AEM)的一部分。但是,Adobe AEM的价格为数十万美元,仅保留给数量有限的公司。

在搜索和尝试几乎所有在线TMS时,我碰到了一个很棒的网站-Linguallo.com,它是SaaS,可以免费使用。免费计划包括无限数量的电子表格,其中每个电子表格可以在每个应用程序中使用,并且每个工作表有500个免费托管键,5种语言和3个用户可以在上面进行协作。以我的拙见,对于大多数公司来说,这是一个不错的选择。该工具与其他工具有什么区别:

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

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

4b2af47be77d6471a90db57c564caed2.png

假设您已经安装了Linguallo CLI,添加新键很简单,只需在项目的工作区中键入以下内容:

translate push --input="./src/locales/dev.json"

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

总结

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

即使它是“三巨头”(Angular,React和Vue)中的最新产品,我也一定会在企业应用程序中尝试一下Vue,因为我已经在与团队进行讨论。多年来,我一直在Angular和React框架中进行开发,同时构建了世界上最大的旅行电子商务Web应用程序之一。

我认为,与React相比,Vue更容易学习。 Vue以Web开发人员已经习惯的方式分离关注点,将HTML,CSS和JavaScript分离。我认为Vue掌握了React和Angular的精髓。

原文:https://levelup.gitconnected.com/advanced-vue-js-internationalization-i18n-and-localization-l10n-using-vue-router-a94ecd83fecd

作者:Ivan Miletic

翻译:做工程师不做码农


本头条号聚焦大前端技术和程序员成长,如果对你有所启发和帮助,可以点个关注、收藏,也可以留言讨论,这是对作者的最大鼓励。

作者简介:Web前端工程师,全栈开发工程师、持续学习者。

#Vue.js#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值