利用Vite2和Vue3实现网站国际化的全过程
作者:木亦Sam 发布时间:2023-07-02 17:09:14
前言
最近有人在吐槽项目使用 Vue3 之后,出现一堆问题,填坑困难,甚至是开发中才发现某些第三方库没有推出 Vue3 的版本,因此大发吐槽,强烈建议不使用 Vue3。
做好技术预研和兼容性调查是开发前的工作之一,特别是对于新技术或者大版本的更新,除非你有十个胆,否则不要在预研不充分的情况下,在正式项目中使用。
最近在将自己的某个 Vue3 的项目接入国际化配置,整体的过程跟 Vue2 并没有太大的区别,在此做下技术经验分享。
安装vue-i18n
npm i vue-i18n --save
这里使用的是 vue-i18n 来实现国际化多语言切换,i18n 这个名字其实是由英文单词 internationalization 的首尾两个字母和中间的字符数 18 组成,意为「国际化」。
配置Locales
在项目 src 中新建 locales 文件夹,在里面新建 language 文件夹,用于存储各个语言的文本配置。language 中新建 en 和 zh-CN 文件夹,并对应的新建 index.js,填充以下内容:
// src/locales/language/zh_CN/index.js
export default {
title: "中文标题",
}
// src/locales/language/en/index.js
export default {
title: "English title",
}
实现 getLangs.js
在 locales 中新建 getLangs.js 文件,用于获取 language 文件夹中的语言包并暴露出去。
这里用到了 lodash-es 插件,你需要安装该插件:
npm i lodash-es --save
具体代码如下:
import { set } from 'lodash-es'
const modules = import.meta.globEager('./language/**/*.js')
function getLanguages(langs, prefix = 'lang') {
const obj = {}
Object.keys(langs).forEach((key) => {
const mod = langs[key].default
let k = key.replace(`./${prefix}/`, '').replace(/^\.\//, '')
const lastIndex = k.lastIndexOf('.')
k = k.substring(0, lastIndex)
const keyList = k.split('/')
const lang = keyList.shift()
const objKey = keyList.join('.')
if (lang) {
set(obj, lang, obj[lang] || {})
set(obj[lang], objKey, mod)
}
})
return obj
}
const { language } = getLanguages(modules)
export default language
创建 i18n 实例
接下来需要创建 i18n 实例,并挂载到 Vue。在 locales 中新建 i18n.js。代码如下:
import { createI18n } from 'vue-i18n'
import messages from './getLangs'
export default createI18n({
legacy: false,
locale: window.localStorage.getItem("lang") || 'zh_CN',
messages,
})
可以看到这里默认的语言配置是从浏览器中 localStorage 中获取的,没有则为 “zh-CN”。在切换语言后,需要将当前语言存起来,不然用户刷新,可就又回到默认语言配置了。
在 main.js 中引入:
import i18n from './locales/i18n'
const app = createApp(App)
app.use(I18n).mount("#app")
模板中使用
这里使用 composition api 的方式引入并使用,在模板对应的位置中,使用 t 函数获取当前语言配置下的展示文本,函数接收语言配置文件和属性的路径,通过点语法连接,如果找不到,则会将整个函数名称以字符形式展示。
<template>
<p>{{t(`index.title`)}}</p>
</template>
import { useI18n } from "vue-i18n";
export default {
setup() {
const { t } = useI18n();
return { t }
}
}
语言切换
常用的语言切换方式有两种,一种是将当前语言配置放到 url 上,切换语言即跳转到对应的路由,再展示当前语言下的对应文本。
第二种是无刷新/跳转的切换,将当前语言存储到本地缓存中,通过修改 vue-i18n 的 locale 的值切换语言。
这里推荐使用第二种,切换语言不需要刷新页面或者采用跳转的形式。
<template>
<a
href="javascript:;"
@click="setLocals(locale === 'zh_CN' ? 'en' : 'zh_CN')"
>
{{ locale === 'zh_CN' ? '英' : '中' }}
</a>
</template>
<script>
import { useI18n } from "vue-i18n";
import { ref } from "@vue/reactivity";
export default {
setup() {
const { t, locale } = useI18n();
const getLocals = () => window.localStorage.getItem("lang") || locale.value;
const currentLocale = ref(getLocals());
const setLocals = (lang = "") => {
locale.value = lang;
window.localStorage.setItem("lang", lang);
};
if (!window.localStorage.getItem("lang")) {
setLocals(currentLocale.value);
} else {
if (currentLocale.value !== locale.value) {
setLocals(currentLocale.value);
}
}
return {
t,
locale,
setLocals,
};
},
};
</script>
初始化的时候,先从本地获取当前语言,如果没有则获取默认的语言配置,切换语言时,不仅需要修改 locale 的值,还需要将当前语言存一份到本地缓存中。
关于切换后需要刷新后才生效
上面的例子,在模板中直接使用 t 函数渲染的文本,在语言切换时是无需刷新即可更新视图语言的,但如果是在 setup 中直接使用 t 函数,则不会立即更新,需要刷新后才生效。
这里不推荐在模板以外的地方使用 t 函数,如有必要,可以在组件中定义多语言文本,在模板中通过键值对的形式去访问。
切换语言触发其他组件更新
在一些场景中,页面展示的文本是通过外部获取的,无法直接由语言切换触发更新,需要实现类似兄弟组件的广播效果。
在 Vue3 中取消了 global bug 的使用,进而可以用 mitt 等插件代替。
来源:https://juejin.cn/post/6991566044674392078
猜你喜欢
- 找了半天,以为numpy的where函数像matlab 的find函数一样好用,能够返回一个区间内的元素索引位置。结果没有。。(也可能是我没
- 一、MySQL-Proxy基础MySQL Proxy是一个处于你的Client端和MySQL server端之间的简单程序,它可以监测、分析
- win2000注册表程序 regedt32.exe下面是解决IIS出现Active Server Pages错误&
- 在很多情况下,我们可能需要控制某一段代码只执行一次,比如做某些初始化操作,如初始化数据库连接等。 对于这种场景,go 为我们提供了 sync
- 目录pyspark创建DataFrameRDD和DataFrame使用二元组创建DataFrame使用键值对创建DataFrame使用rdd
- 前言:👉对于新手来说,库的安装是遇到的第一个挑战,我也入了很多坑,所以想出一期安装库的步骤,由于博主水平限制,博客难免会有错误和不准之处,我
- 本文讲述使用JSP实现用户登录,包括用户登录、注册和退出功能等。1.系统用例图2.页面流程图3.数据库设计本例使用oracle数据库创建用户
- 这篇文章主要介绍了opencv python Canny边缘提取实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的
- Pytest使用的断言是使用python内置的断言assert。Python assert(断言)用于判断一个表达式,在表达式条件为 fal
- 前言在日常中有时需将 html 文件转换为 pdf、word 文件。网上免费的大多数不支持多个文件转换的情况,而且在转换几个后就开始收费了。
- 如下所示:'''@author: Jacobpc'''import osimport sys
- 在防止sql注入这些细节出现问题的一般是那些大意的程序员或者是新手程序员,他们由于没有对用户提交过来的数据进行一些必要的过滤,从而导致了给大
- 目录MySQL数据库重命名的方法 第一种方法:rename database 弃用了第二种方法:mysqldump 备份第三种方法
- 1. Python中lib、package和module的关系module:以.py为结尾的文件都是模块。package:就是一个带__in
- 软件版本及平台:MySQL-5.7.17-winx64,win7家庭版一、下载安装包https://cdn.mysql.com//Downl
- 前言:之前自己做一个uni-app的项目的时候前端需要实现一个比较复杂的动态tab和swiper切换的功能,但是由于自己前端抠脚的原因没有写
- 这周心血来潮,翻看了现在比较流行的几个JS脚本框架的底层代码,虽然是走马观花,但也受益良多,感叹先人们的伟大……感叹是为了缓解严肃的气氛并引
- 以控制抖音app滑动并获取抖音短视频发布者昵称和点赞数等信息为例:1. 安装appium-python-client模块并启动已安装好的环境
- 3*3卷积核与2*5卷积核对神经元大小的设置#这里kerner_size = 2*5class CONV_NET(torch.nn.Modu
- 今天安装了ubuntu的虚拟机,并安装了mysql8.0.28版本的数据库,供大家参考,具体内容如下修改密码改了挺长时间,记录下安装过程安装