vue3使用插件i18n实现国际化多语言

目录

1. 需求说明

2. 安装i18n插件及配置

2.1 执行命令安装i18n

2.2 配置

2.2.1 新建目录及文件夹

2.2.2 lang/zh.js

2.2.3 lang/en.js

2.2.4 lang/index.js

2.2.5 src/main.js 引入i18n

 3. 安装及配置路由

3.1 执行命令安装路由

 3.2 配置路由

 3.3 在main.js 引入router

3.4 在App.vue 设置路由守卫

 4. 切换语言下拉框及逻辑

4.1 页面效果

4.2 代码展示 HomeView.vue


1. 需求说明

网站(https:example.com/homeView)支持繁体中文、英文,法语,日语,阿拉伯语,且要求默认路径下是英文,其他的语言切换要显示在路径上如https:example.com/zh/homeView.

2. 安装i18n插件及配置

2.1 执行命令安装i18n

npm install vue-i18n@next --save
或者
yarn add vue-i18n@next --save

2.2 配置

2.2.1 新建目录及文件夹

- src

    - locales

        - lang

            - zh.js

            - en.js

            - ar.js

            - jp.js

            - fr.js

        - index.js

2.2.2 lang/zh.js
const zh = {
    test: "測試",
    Credits: "積分"
}
export default zh;
2.2.3 lang/en.js
const en = {
    test: "test",
    Credits: "Credits"
}
export default en;

        lang下的其他文件仿照上述改写一下就好了

2.2.4 lang/index.js
import { createI18n } from "vue-i18n";     // 引入vue-i18n组件
import zh from "./lang/zh";     // 引入zh.js 模块
import en from "./lang/en";     // 引入en.js 模块
import jp from "./lang/jp";     // 引入日语模块
import ar from "./lang/ar";     // 引入阿拉伯语 模块
import fr from "./lang/fr";     // 引入法语模块


export const getCurrLang = () => {
    // const localLang = navigator.language.split('-')[0]; // 浏览器语言
    const localStorageLang = localStorage.getItem("localeKey");// 本地存储语言
    return localStorageLang || 'en';
}

//注册i18n实例并引入语言文件
const i18n = createI18n({
    legacy: false,
    locale: 'en', // 语言标识
    fallbackLocale: "en", //没有英文的时候默认中文语言
    messages: {
        zh,
        en,
        jp,
        ar,
        fr
    },
});
export default i18n;


2.2.5 src/main.js 引入i18n
import { createApp } from 'vue'
import App from './App.vue'
import i18n from "./locales/i18n";

const app = createApp(App)
app.use(i18n).mount('#app');

 3. 安装及配置路由

3.1 执行命令安装路由

npm install vue-router --save
或者
yarn add vue-router --save

 3.2 配置路由

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '@/views/HomeView.vue'

const routes = [
  {
    path: '/',
    redirect: `/homeView`
  },
  {
    path: '/:locale?/homeView',
    name: 'HomeView',
    component: HomeView,
    meta: {
      title: 'HomeView'
    }
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

 3.3 在main.js 引入router

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router).mount('#app')

3.4 在App.vue 设置路由守卫

<template>
  <div>
    <router-view />
  </div>
</template>

<script>
import { defineComponent } from "vue";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";

export default defineComponent({
  setup() {
    // 路由守卫
    const router = useRouter();
    const i18n = useI18n();
    router.beforeEach((to, from, next) => {
      // 检查to.params.locale 是否存在,并设置相应的语言环境或执行其他逻辑
      const lang = to.params.locale;
      localStorage.setItem("localeKey", lang || "en");
      i18n.locale.value = lang || "en";
      // 放这才能根据语言设title标签内容
      document.title =
        to.meta.title || "home";
      next(); // 确保要调用next方法
    });
  },
});
</script>

 4. 切换语言下拉框及逻辑

4.1 页面效果

4.2 代码展示 HomeView.vue

<template>
  <div style="display: flex;">
    <div style="margin: 25px;">{{ credits }}</div>
    <div class="item lang">
      <a-dropdown :trigger="['click']" v-model:visible="visible" placement="top">
        <a class="ant-dropdown-link" @click.prevent>
          <span class="text">{{ currentLang }}</span>
          <DownOutlined class="icon" v-show="visible" />
          <UpOutlined class="icon" v-show="!visible" />
        </a>
        <template #overlay>
          <a-menu @click="onClickMenu">
            <a-menu-item v-for="item in localArr" :key="item.key"> {{ item.name }} </a-menu-item>
          </a-menu>
        </template>
      </a-dropdown>
    </div>
  </div>
</template>
<script>
import { computed, defineComponent, ref, getCurrentInstance, watch } from "vue";
import { DownOutlined, UpOutlined } from "@ant-design/icons-vue";
import { useI18n } from "vue-i18n";
import i18nLanguage from "@/locales/i18n";
import { useRouter } from "vue-router";
export default defineComponent({
  components: {
    DownOutlined,
    UpOutlined,
  },
  props: {},
  setup() {
    // 定义key对应的语言
    const localArr = [
      { key: "zh", name: "中文" },
      { key: "en", name: "English" },
      { key: "jp", name: "日本です" },
      { key: "ar", name: "العربية" },
      { key: "fr", name: "français" },
    ]

    const getCurrentLang = (lang) => {
      return localArr.find(item => item.key == lang).name || "English"
    }

    // 在js中使用多语言,第一种
    // const credits = computed(() => {
    //   return i18nLanguage.global.t("Credits")
    // })

    //第二种:也可以通过组件实例,getCurrentInstance 只能在 setup 或生命周期钩子中使用
    const _this = getCurrentInstance().appContext.config.globalProperties;
    const credits = computed(() => _this.$t("Credits"))

    const visible = ref(false);
    const i18n = useI18n();
    const router = useRouter();

    let currentLang = ref(getCurrentLang(localStorage.getItem("localeKey") || "en"));
    watch(() => i18n.locale.value, (val) => {
      currentLang.value = getCurrentLang(val)
    }, {
      immediate: true
    })
    const onClickMenu = (e) => {
      i18n.locale.value = e.key;
      // 存入缓存
      localStorage.setItem("localeKey", e.key);
      // 设置页面显示的语言
      currentLang.value = getCurrentLang(e.key);
      // 下拉框收起
      visible.value = false;
      // 改变路由路径
      if (e.key !== "en") {
        router.push({ params: { locale: i18n.locale.value } });
      } else {
        router.push({ params: { locale: "" } });
      }
    };
    return {
      localArr,
      visible,
      onClickMenu,
      currentLang,
      credits
    };
  },
});
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值