1. 基本方法

在 Vue.js 3 中实现网页的国际化多语言,最常用的包是 vue-i18n,通常我们会与 vue-i18n-routing 一起使用。

vue-i18n 负责根据当前页面的语言渲染文本占位符,例如:

<span>{{ t('Login') }}</span>

当语言设置为中文时,会将 Login 渲染为“登录”。

vue-i18n-routing 负责将页面语言与 URL 绑定,例如:

https://githubstar.pro/zh-CN/repo

表示访问中文版的 /repo 路径。

将不同语言的网页放在不同的 URL 下有助于 SEO,因为可以在 <head> 部分添加语言信息,增加不同语言被搜索引擎索引的概率。

Google 对于多语言 Vue 站点的爬取机制如下:

  1. 类似 Vue 站点的 JS 动态页面是可以被爬取的,不影响权重 (参见 Google SEO)。
  2. 与用户首选语言匹配的页面将优先展示 (参见 Google SEO)。

2. 基础实现

第一步,安装一个 Vite 下使用 <i18n> 标签的插件:unplugin-vue-i18n

然后调整 vite.config.js

import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import VueDevTools from 'vite-plugin-vue-devtools';
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'; export default defineConfig({
plugins: [
vue(),
VueDevTools(),
VueI18nPlugin({}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
});

添加插件后,我们可以在组件内使用 <i18n> 块:

<script setup lang="ts">
import { useI18n } from 'vue-i18n'; const { t, locale } = useI18n({ inheritLocale: true, useScope: 'local' });
</script> <template>
<span>{{ t('Login') }}</span>
</template> <i18n lang="yaml">
en:
Login: 'Login to web'
zh-CN:
Login: '登录'
</i18n>

这里我们定义了两种不同的语言。

3. 路径绑定

接下来,我们需要定义使用 URL 作为当前语言,编辑 router/index.ts

import { createRouter as _createRouter, type RouteLocationNormalized } from 'vue-i18n-routing';
import { createWebHistory } from 'vue-router';
import HomeView from '@/views/HomeView.vue'; const locales = [
{
code: 'en',
iso: 'en-US',
name: 'English',
},
{
code: 'zh-CN',
iso: 'zh-CN',
name: '中文',
},
]; export function createRouter(i18n: any) {
const router = _createRouter(i18n, {
version: 4,
locales: locales,
defaultLocale: 'zh-CN',
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/home',
name: 'home',
component: HomeView,
},
],
});
return router;
}

我们定义了支持的语言种类,并将原来的 routes 包装起来,vue-i18n-routing 会自动生成所有支持语言的 routes

  • /home = 中文
  • /en/home = 英文

由于我们设置了 defaultLocale: 'zh-CN',默认路径为中文。

然后,我们需要将源代码中涉及跳转的部分,例如:

router.push({ name: 'home' });

全部加上 localePath,表示是当前语言的 URL 路径下:

import { useLocalePath } from 'vue-i18n-routing';

const localePath = useLocalePath();

router.push(localePath({ name: 'home' }));

这样就完成了路径绑定。

4. 自动切换

有时,我们希望没有默认语言,而是根据用户的浏览器语言自动选择:

  • /zh-CN/home = 中文
  • /en/home = 英文
  • /home -> 重定向 (浏览器偏好中文) -> /zh-CN/home = 中文
  • /home -> 重定向 (浏览器偏好英文) -> /en/home = 英文

这时我们需要定义一个 store,这里使用 Pinia store,Vuex 同理。

import { usePreferredLanguages, useStorage } from '@vueuse/core';
import { defineStore } from 'pinia'; export const useLangStore = defineStore('lang', {
state: () => {
const savedLang = useStorage<string | null>('lang', null, undefined);
const systemLang = usePreferredLanguages();
return { savedLang, systemLang };
},
getters: {
lang: (state) => {
const lang = state.savedLang || state.systemLang[0];
if (lang.startsWith('zh')) {
return 'zh-CN';
} else {
return 'en';
}
},
},
actions: {
setLang(l?: string) {
if (!l) {
this.savedLang = null;
} else {
this.savedLang = l;
}
},
}
});

这段代码使用了 VueUse 中的 usePreferredLanguages 来获得用户偏好的浏览器语言,并用 useStorage 添加了一个 LocalStorage 中的存储项。

逻辑是:如果用户手动设定了语言(savedLang),则使用之;如果没有,则使用系统偏好的第一个语言。这样,我们只要取 lang 的值就可以得到最终的偏好语言是中文还是英文。

然后,我们需要定义一个路径守卫,以自动处理 URL 中没有语言的情况。

import { createRouter as _createRouter, type RouteLocationNormalized } from 'vue-i18n-routing';
import { createWebHistory } from 'vue-router';
import HomeView from '@/views/HomeView.vue'; const locales = [
{
code: 'en',
iso: 'en-US',
name: 'English',
},
{
code: 'zh-CN',
iso: 'zh-CN',
name: '中文',
},
{
code: '',
iso: '',
name: '',
}
]; export function createRouter(i18n: any) {
const router = _createRouter(i18n, {
version: 4,
locales: locales,
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/home',
name: 'home',
component: HomeView,
},
],
});
router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized) => {
const lang = useLangStore();
const pathLocale = to.path.split('/')[1];
if ((!pathLocale) || (!locales.some(locale => locale.code === pathLocale))) {
return `/${lang.lang}${to.path}`;
}
});
return router;
}

这里需要注意三点:

  1. 我们增加了一个新的空 locales,这样请求才能到达 router.beforeEach
  2. 我们去掉了 defaultLocale
  3. 使用刚才定义的 store:useLangStore() 这行代码必须放在 router.beforeEach 中,而不能放在模块顶端,因为加载模块时 Pinia 还没有启动。

这样,就实现了无语言路径自动跳转到当前偏好语言路径。

5. 导航栏切换按钮

然后,可以在导航栏增加一个按钮,来手动切换语言,例如:

<script setup lang="ts">
import { useLocalePath, useSwitchLocalePath } from 'vue-i18n-routing';
import { useLangStore } from '@/stores/lang'; const lang = useLangStore();
const { t, locale } = useI18n({ inheritLocale: true, useScope: 'local' });
</script> <template>
<div
@click="
lang.setLang('en');
router.push(switchLocalePath('en'));
menuShown = '';
"
class="py-2 px-2 gap-2 flex items-center cursor-pointer hover:bg-slate-400/10"
:class="{ 'text-sky-300': locale == 'en' }"
role="option"
tabindex="-1"
:aria-selected="locale == 'en'"
>
<IconEnglish class="w-5 h-5 text-slate-400 dark:text-slate-200" />
English
</div>
<div
@click="
lang.setLang('zh-CN');
router.push(switchLocalePath('zh-CN'));
menuShown = '';
"
class="py-2 px-2 gap-2 flex items-center cursor-pointer hover:bg-slate-400/10"
:class="{ 'text-sky-300': locale == 'zh-CN' }"
role="option"
tabindex="-1"
:aria-selected="locale == 'zh-CN'"
>
<IconChinese class="w-5 h-5 text-slate-400 dark:text-slate-200" />
中文
</div>
</template>

这里,我们在刚才定义的 store 中存储当前手动设定的语言,同时使用 switchLocalePath 来实现路径和语言的切换。

6. SEO 和 Head Meta

同一内容的不同语言版本应该在 head 中进行标注,并指向所有其他替代页面(参见 Google SEO)。这里我们可以在 App.vue 中用 useLocaleHead 和来自 @unhead/vue 包的 useHead 进行设置:

import { useLocaleHead } from 'vue-i18n-routing';
import { useHead } from '@unhead/vue'; const i18nHead = useLocaleHead({ addSeoAttributes: true, defaultLocale: null, strategy: null }); onMounted(() => {
useHead({
htmlAttrs: computed(() => ({
lang: i18nHead.value.htmlAttrs!.lang,
})),
link: computed(() => [...(i18nHead.value.link || [])]),
meta: computed(() => [...(i18nHead.value.meta || [])]),
});
});

这样就基本实现了一个多语言的国际化站点。可能在进行前端翻译的同时,后端也需要进行翻译,请期待下一期:Python Flask 后端如何接入 i18n 实现国际化多语言!

6. 案例分析

案例:GithubStar.Pro 的前端界面国际化多语言,是使用本文所述的方法实现的,各位可以看看效果。

也欢迎各位使用 GithubStar.Pro 互赞平台,提高您的开源项目知名度,收获更多用户。

Vue3 如何接入 i18n 实现国际化多语言的更多相关文章

  1. php gettext方式实现UTF-8国际化多语言(i18n)

    php gettext方式实现UTF-8国际化多语言(i18n) 一.总结 一句话总结: 二.php gettext方式实现UTF-8国际化多语言(i18n) 近 来随着i18n(国际化)的逐渐标准化 ...

  2. WPF 实际国际化多语言界面

    前段时候写了一个WPF多语言界面处理,个人感觉还行,分享给大家.使用合并字典,静态绑定,动态绑定.样式等东西 效果图 定义一个实体类LanguageModel,实际INotifyPropertyCha ...

  3. Go Revel - i18n(国际化)

    ##Messages `Messages`信息是对内容提供翻译的外部文本片段.revel提供了组织每一种语言文本片段的message文件.自动区域查找.基于cookie覆盖的消息嵌套和参数. 术语表: ...

  4. [Spring]Spring Mvc实现国际化/多语言

    1.添加多语言文件*.properties F64_en_EN.properties详情如下: F60_G00_M100=Please select data. F60_G00_M101=Are yo ...

  5. yii2 api接口 实现国际化多语言设置

    1) 在 /config/main.php 下添加如下代码: 'components' => [ 'language' => 'zh-CN', 'i18n' => [ 'transl ...

  6. iOS 国际化多语言设置 xcode7

    iOS 国际化多语言设置 方式一: 1. 在storyboard中创建好UI,然后在 project 里面  Localizables 栏目里面,添加你需要的语言:默认是Englist; 比如这里我添 ...

  7. 更好用的excel国际化多语言导出

    不知道大家在开发中有没有遇到过『excel导出』的需求,反正我最近写了不少这种功能,刚开始利用poi,一行行的手动塞数据,生成excel,而且还有国际化需求,比如:标题栏有一列,用户切换成" ...

  8. iOS 学习笔记六 【APP中的文字和APP名字的国际化多语言处理】

    今天为新手解决下APP中的文字和APP名字的国际化多语言处理, 不多说了,直接上步骤: 1.打开你的项目,单机project名字,选中project,直接看图吧: 2.创建Localizable.st ...

  9. Blazor 国际化多语言界面 (I18nText )

    在实际使用中,我们经常会遇到需要把程序界面多种语言切换,适应不同地区使用者的需求,本文介绍一个我初学Blazor接触到的库,边撸边讲解. 包名: Toolbelt.Blazor.I18nText ht ...

  10. vue-cli之路由独立成JS文件之后,如何在路由中获取vuex属性或者设置国际化i18n的当前使用语言

    国际化vue-i18n的使用: import Vue from 'vue'; import VueI18n from 'vue-i18n'; // 引入语言包 import zh from '@/co ...

随机推荐

  1. centos7桌面版安装百度网盘

    百度网盘官网下载Linux版本的软件 CentOS7的软件包格式为rpm # 安装依赖 yum -y install libXScrnSaver yum -y install libstdc++.so ...

  2. UnityShader数学基础篇

    Mathf Mathf和Math 1.Math是C#中封装好的用于数学计算的工具类,位于System命名空间中. 2.Mathf是Unity中封装好的用于数学计算的工具结构体,位于UnityEngin ...

  3. MPI学习笔记(四):矩阵相乘的Cannon卡农算法

    mpi矩阵乘法:C=αAB+βC 一.Cannon卡农算法基本介绍 1.二维矩阵串行乘法 两个n维方阵的乘法A×B=C的串行计算公式为: 下图是用图示来表示的这种计算规则: 2.二维块划分的思想 并行 ...

  4. mysql 命令行安装方式

    一:下载 先到 mysql 官方网站下载:https://dev.mysql.com/downloads/mysql/ 点击直接下载: 解压到目录:D:\mysql-8.0.19-winx64  如图 ...

  5. Linux之命令提示符的颜色设置

    1.临时设置 执行下面的命令: export PS1="[\[\e[34;1m\]\u@\[\e[0m\]\[\e[32;1m\]\H\[\e[0m\] \[\e[31;1m\]\w\[\e ...

  6. cmd命令行设置 windows 设置环境变量

    设置用户级别的环境变量 :: 设置新参数 JAVA_HOME1 setx JAVA_HOME1 "c:\test"; exit; echo "%JAVA_HOME1%&q ...

  7. Hangfire 使用笔记 任务可以分离到别的项目中,无需重复部署Hangfire,通过API方式通信。

    "巨人们"的地址 Hangfire Mysql: https://github.com/arnoldasgudas/Hangfire.MySqlStorage 在获取set表数据的 ...

  8. boss直聘__zp_stoken__逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 aHR0cHM6 ...

  9. 判断是不是ie浏览器 加上ie11

    var b_version = navigator.appVersion; var version = b_version.split(";"); var trim_Version ...

  10. webpack配置图片处理

    # 安装 npm i -D url-loader html-loader file-loader # loader配置 module: { rules: [ // 图片处理 { test: /\.(p ...