利用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

    标签:vite2,vue3,国际化
    0
    投稿

    猜你喜欢

  • python3代码输出嵌套式对象实例详解

    2021-09-16 07:35:55
  • python接口测试对修改密码接口进行压测

    2022-05-16 04:26:15
  • MySQL Semisynchronous Replication介绍

    2024-01-12 19:42:02
  • 用TensorFlow实现lasso回归和岭回归算法的示例

    2021-09-08 19:48:30
  • tensorflow 用矩阵运算替换for循环 用tf.tile而不写for的方法

    2021-08-11 11:43:55
  • python爬取基于m3u8协议的ts文件并合并

    2021-11-03 16:44:45
  • mssql server 数据库附加不上解决办法分享

    2011-09-30 11:55:20
  • pip如何用pipdeptree查看包依赖

    2022-07-28 01:56:26
  • 用ASP和XMLHTTP分析远程XML文件

    2007-12-12 12:48:00
  • python使用requests实现发送带文件请求功能

    2023-11-03 14:23:13
  • 利用python判断字母大小写的几种方法小结

    2022-05-10 16:41:49
  • TensorFlow实现iris数据集线性回归

    2023-11-14 09:56:39
  • Python使用Crypto库实现加密解密的示例详解

    2021-11-10 05:53:10
  • Python实现文件及文件夹操作大全

    2021-05-22 09:35:21
  • Python正则表达式学习小例子

    2023-01-30 21:57:42
  • 关于python3安装pip及requests库的导入问题

    2021-10-06 11:23:26
  • ASP实现GB2312转UTF-8函数

    2009-02-26 13:08:00
  • SQL语句实现删除ACCESS重复记录的两种方法

    2024-01-24 21:43:25
  • python各类经纬度转换的实例代码

    2023-12-24 12:19:58
  • SQL server中字符串逗号分隔函数分享

    2024-01-12 17:20:22
  • asp之家 网络编程 m.aspxhome.com