Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

news2025/4/20 6:49:32

目录

  • Vue 3 国际化实战:支持 Element Plus 组件和语言持久化
    • 实现效果:
      • 效果一、中英文切换
      • 效果二、本地持久化存储
      • 效果三、element Plus国际化
    • vue3项目国际化实现步骤
      • 第一步、安装`i18n`
      • 第二步、配置`i18n`的`en`和`zh`
      • 第三步:使用 `vue-i18n` 库来实现多语言支持
      • 第四步、本地持久化
      • 第五步、main.ts挂载
      • 第六步、页面使用测试效果
      • 第七步、 `Element Plus`的国际化操作
      • 第八步、element Plus国际化效果测试
    • 问题总结:
      • 问题一、如何在js种使用
      • 问题二、elementPlud表单校验提示不生效问题

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

i18n来源于英文单词internationalization的首末字母in,18为中间的字符数,是"国际化"的简称,在资迅领域,国际化(i18n)指产品,出版物,软件,硬件等无需做大的改变就能适应不同的语言和地区的需要,对前端开发来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面,在全球化时代,国际化尤为重要,因为产品的潜在用户可能来自世界各个国家,通常与i18n相关的还有L10n本地化的简称。

实现效果:

效果一、中英文切换

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

效果二、本地持久化存储

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

效果三、element Plus国际化

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

vue3项目国际化实现步骤

第一步、安装i18n

vue3中需要安装的版本是v9版本

 npm install vue-i18n@9

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化
Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

第二步、配置i18nenzh

  1. 创建src/locales/en.json
    {
      "header": {
        "title": "JuBo Vision · AI Intelligent Inspection System",
        "home": "Home",
        "systemConfiguration": "System Configuration",
        "inspectionSettings": "Inspection Settings",
        "faultConfiguration": "Fault Configuration",
        "logs": "Logs"
      }
    }
    
  2. 创建src/locales/zh.json
    	{
      "header": {
        "title": "聚玻Vision ·AI智能检测系统",
        "home": "首页",
        "systemConfiguration": "系统配置",
        "inspectionSettings": "检测配置",
        "faultConfiguration": "故障配置",
        "logs": "日志"
      }
    }
    

第三步:使用 vue-i18n 库来实现多语言支持

创建src/locales/index.ts,其中代码步骤:

  1. vue-i18n中导入用于创建 i18n 实例的方法。
  2. 分别导入中文和英文的语言资源文件(enzhJSON 格式)。
  3. 通过navigator.language获取用户语言环境。
  4. 检查本地缓存的语言设置,如果本地存储中有值,则解析 JSON 数据并提取 curLocale 字段作为当前语言。
  5. 创建 i18n 实例。
  6. 定义支持的语言列表。

整体代码:

import { createI18n } from 'vue-i18n'
import zh from './zh.json'
import en from './en.json'

// 获取浏览器界面语言,默认语言
let currentLanguage = navigator.language.replace(/-(\S*)/, '')

// 如果本地缓存记录了语言环境,则使用本地缓存
let lsLocale = localStorage.getItem('locale') || ''
if (lsLocale) {
  currentLanguage = JSON.parse(lsLocale)?.curLocale
}

export const i18n = createI18n({
  locale: currentLanguage,
  legacy: false, // 修复组件引入i18n时vite脚手架报错的问题
  globalInjection: true, // 全局注册 $t
  messages: {
    zh,
    en
  }
})

export const langs = [
  { key: 'zh', title: '中文' },
  { key: 'en', title: 'English' }
]

第四步、本地持久化

当我们把中文改成English后,再刷新页面,语言环境又会回到中文,所以我们需要做一点工作来保持国际化状态。
创建src/stores/locales.ts文件,代码如下:

import { defineStore } from 'pinia'
import { ref } from 'vue'
import { i18n } from '../locales/index'
export const useLocaleStore = defineStore(
  'locale',
  () => {
    // 初始化时从 localStorage 获取语言设置,默认为 'en'
    const locale = ref(localStorage.getItem('user-locale') || i18n.global.locale.value);

    // 设置locale
    function setLocale(lang: any) {
      locale.value = lang
      i18n.global.locale.value = lang
      localStorage.setItem('user-locale', lang); // 持久化存储到 localStorage
    }
    return { locale, setLocale }
  }
)

第五步、main.ts挂载

import { createApp, watch } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import router from './router';
// 整合ElementPlus
import ElementPlus from 'element-plus';
// 样式文件,elemen-plus样式在index.scss中导入了
import '@/styles/index.scss';
// 图标
import { useElIcon } from '@/utils/setGlobal';
// 国际化
import { i18n } from './locales/index'
// 引入 Pinia Store
import { useLocaleStore } from './stores/locales';
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.use(i18n)
app.use(ElementPlus);
// 初始化语言设置
const localeStore = useLocaleStore();
const currentLocale = localeStore.locale;
// 同步 i18n 的语言设置
localeStore.setLocale(currentLocale);
// 全局注册图标`ele-`开头(样式在index.scss中)
useElIcon(app);
app.mount('#app')

第六步、页面使用测试效果

代码:

<template>
  <!-- 右侧头部区域 -->
  <el-header class="layout-header">
    <div class="header-box">
      <logo />
    </div>
    <div
      class="header-navigation-bar"
      style="display: flex; justify-content: space-between"
    >
      <div style="width: 50%">
        <el-menu
          :router="true"
          :default-active="$route.path"
          class="el-menu-demo"
          mode="horizontal"
          @select="handleSelect"
        >
          <el-menu-item index="/">{{ $t("header.home") }}</el-menu-item>
          <el-menu-item index="/systemSetting">{{
            $t("header.systemConfiguration")
          }}</el-menu-item>
          <el-sub-menu index="/detectionConfig">
            <template #title>{{ $t("header.inspectionSettings") }}</template>
            <el-menu-item index="/detectionConfig">{{
              $t("header.inspectionSettings")
            }}</el-menu-item>
            <el-menu-item index="/faultConfig">{{
              $t("header.faultConfiguration")
            }}</el-menu-item>
          </el-sub-menu>
          <el-menu-item index="/log">
            {{ $t("header.logs") }}
          </el-menu-item>
        </el-menu>
      </div>
      <el-date-picker type="datetime" placeholder="Select date and time" />
      <div style="margin-right: 50px; height: 30px">
        <el-dropdown
          @command="handleCommand"
          style="width: 80px; line-height: 30px"
        >
          <div class="el-dropdown-link" style="display: flex">
            <div>{{ currentLan }}</div>
            <div style="line-height: 30px; line-height: 37px; margin-left: 4px">
              <SvgIcon name="ele-ArrowDown"></SvgIcon>
            </div>
          </div>

          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item
                v-for="lang in langs"
                :key="lang.key"
                :command="lang"
                >{{ lang.title }}</el-dropdown-item
              >
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </div>
  </el-header>
</template>
<script setup lang="ts" name="LayoutHeader">
import { defineAsyncComponent } from "vue";
import { ref } from "vue";

//正确用法
import { langs } from "../../locales/index"; //这个是你自己的国际化配置文件

import { useLocaleStore } from "../../stores/locales";
import { getCurrentInstance } from "vue";
const Logo = defineAsyncComponent(() => import("./logo.vue"));
const useLocale = useLocaleStore();

const handleSelect = (key: string, keyPath: string[]) => {
  console.log(key, keyPath);
};
const app = getCurrentInstance();
let curLocale = useLocale.locale;
let currentLan = ref(langs.find((cur) => cur.key === curLocale)?.title || "");

const handleCommand = (command: any) => {
  currentLan.value = command.title;
  // i18n.global.locale.value = command.key; // 设置初始语言
  useLocale.setLocale(command.key);
};
</script>
<style scoped lang="scss">
.el-menu--horizontal {
  --el-menu-horizontal-height: 30px;
}
.header-box {
  height: 52px;
  width: 100;
  background-color: white;
  line-height: 52px;
  border-bottom: 1px solid #f3f3f3;
}
.header-navigation-bar {
  height: 30px;
  width: 100%;
}
</style>

效果:Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

第七步、 Element Plus的国际化操作

使用 Element Plus 提供的语言切换 APIElLocaleProviderel-config-provider 组件),可以实现 Element Plus 组件的动态国际化!你只需要在 App.vue 中包一层配置组件就可以了。

<script setup lang='ts'>
import { computed } from "vue";
import { useLocaleStore } from "./stores/locales";
import zhCn from "element-plus/es/locale/lang/zh-cn";
import en from "element-plus/es/locale/lang/en";

const localeStore = useLocaleStore();
const currentLocale = computed(() => {
  return localeStore.locale === "zh" ? zhCn : en;
});
</script>
<template>
  <!-- 不要少了`class="h100"` 高度100%,不然布局的高度无法占满 -->
  <div class="h100">
    <!-- 路由组件渲染出品 -->
    <!-- <router-view></router-view> -->
    <el-config-provider :locale="currentLocale">
      <router-view />
    </el-config-provider>
  </div>
</template>
<style scoped>
</style>

第八步、element Plus国际化效果测试

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化
刷新持久化存储:
Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

问题总结:

问题一、如何在js种使用

import { ElMessage } from "element-plus";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
ElMessage.error(t("login.loginFail"));

问题二、elementPlud表单校验提示不生效问题

正常去写发现数据没热更新,使用了computed去写
无法热更新写法:

const loginRules = reactive<FormRules>({
  username: [
    {
      required: true,
      message: t("login.userNamePlaceholder"),
      trigger: "blur",
    },
  ],
  password: [
    { required: true, message: t("login.userPwdPlaceholder"), trigger: "blur" },
  ],
});

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化
直接使用computed包住整个校验后的写法:

const loginRules = computed(() => ({
  username: [
    {
      required: true,
      message: t("login.userNamePlaceholder"),
      trigger: "blur",
    },
  ],
  password: [
    { required: true, message: t("login.userPwdPlaceholder"), trigger: "blur" },
  ],
}));

效果:
英文状态:
Vue 3 国际化实战:支持 Element Plus 组件和语言持久化
中文状态
Vue 3 国际化实战:支持 Element Plus 组件和语言持久化
完美解决无法热更新问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2335560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.阿里云快速部署Dify智能应用

一、宝塔面板 宝塔面板是一款功能强大且易于使用的服务器管理软件&#xff0c;支持Linux和Windows系统&#xff0c;通过web端可视化操作&#xff0c;优化了建站流程&#xff0c;提供安全管理、计划任务、文件管理以及软件管理等功能。 1.1 宝塔面板的特点与优势 易用性 宝塔面…

在pycharm配置虚拟环境和jupyter,解决jupyter运行失败问题

记录自己pycharm环境配置和解决问题的流程。 解决pycharm无法运行jupyter代码&#xff0c;仅运行import板块显示运行失败&#xff0c;但是控制台不输出任何错误信息&#xff0c;令人困惑。 遇到的问题是&#xff1a;运行代码左下角显示运行失败但是有没有任何的输出错误信息。 …

【Docker】离线安装Docker

背景 离线安装Docker的必要性&#xff0c;第一&#xff0c;在目前数据安全升级的情况下&#xff0c;很多外网已经基本不好访问了。第二&#xff0c;如果公司有对外部署的需求&#xff0c;那么难免会存在对方只有内网的情况&#xff0c;那么我们就要做到学会离线安装。 下载安…

极简cnn-based手写数字识别程序

1.先看看识别效果&#xff1a; 这个程序识别的是0~9的一组手写数字&#xff0c;这是最终的识别效果&#xff0c;为1&#xff0c;代表识别成功&#xff0c;0为失败。 然后数据源是&#xff1a;ds deeplake.load(hub://activeloop/optical-handwritten-digits-train)里面是一组…

C++核心机制-this 指针传递与内存布局分析

示例代码 #include<iostream> using namespace std;class A { public:int a;A() {printf("A:A()的this指针&#xff1a;%p!\n", this);}void funcA() {printf("A:funcA()的this指针&#xff1a;%p!\n", this);} };class B { public:int b;B() {prin…

vue3 history路由模式刷新页面报错问题解决

在使用history路由模式时刷新网页提示404错误&#xff0c;这是改怎么办呢。 官方解决办法 https://router.vuejs.org/zh/guide/essentials/history-mode.html

PHP爬虫教程:使用cURL和Simple HTML DOM Parser

一个关于如何使用PHP的cURL和HTML解析器来创建爬虫的教程&#xff0c;特别是处理代理信息的部分。首先&#xff0c;我需要确定用户的需求是什么。可能他们想从某个网站抓取数据&#xff0c;但遇到了反爬措施&#xff0c;需要使用代理来避免被封IP。不过用户没有提到具体的目标网…

3.2.2.1 Spring Boot配置静态资源映射

在Spring Boot中配置静态资源映射&#xff0c;可以通过默认路径或自定义配置实现。默认情况下&#xff0c;Spring Boot会在classpath:/static/等目录下查找静态资源。若需自定义映射&#xff0c;可通过实现WebMvcConfigurer接口的addResourceHandlers方法或在全局配置文件中设置…

# 更换手机热点后secureCRT无法连接centOS7系统

更换手机热点后secureCRT无法连接centOS7系统 一、问题描述 某些情况下&#xff0c;我们可能使用手机共享热点而给电脑联网。本来用一个手机热点共享网络时&#xff0c;SecureCRT可以正常连接到CentOS 7虚拟机&#xff0c;当更换一个手机热点时&#xff0c;突然发现SecureCR…

jupyter notebook 无法启动- markupsafe导致

一、运行jupyter notebook和Spyder报错&#xff1a;(已安装了Anaconda&#xff0c;以前可打开) 1.背景&#xff1a;为了部署机器学习模型&#xff0c;按教程直接安装了flask 和markupsafe&#xff0c;导致jupyter notebook&#xff0c;Spyder 打不开。 pip install flas…

CTF web入门之命令执行 完整版

web29 文件名过滤 由于flag被过滤,需要进行文件名绕过,有以下几种方法: 1.通配符绕过 fla?.* 2.反斜杠绕过 fl\ag.php 3.双引号绕过 fl’‘ag’.php 还有特殊变量$1、内联执行等 此外 读取文件利用cat函数,输出利用system、passthru 、echo echo `nl flag.php`; ec…

Java 开发工具:从 Eclipse 到 IntelliJ IDEA 的进化之路

Java 开发工具&#xff1a;从 Eclipse 到 IntelliJ IDEA 的进化之路 在 Java 开发的历史长河中&#xff0c;开发工具的演变不仅改变了程序员的编码方式&#xff0c;也深刻影响了整个行业的开发效率和代码质量。从 Eclipse 到 IntelliJ IDEA&#xff0c;这不仅是工具的更替&…

GPT - 2 文本生成任务全流程

数据集下载 数据预处理 import json import pandas as pdall_data []with open("part-00018.jsonl",encoding"utf-8") as f:for line in f.readlines():data json.loads(line)all_data.append(data["text"])batch_size 10000for i in ran…

红宝书第四十三讲:基于资料的数据可视化工具简单介绍:D3.js 与 Canvas绘图

红宝书第四十三讲&#xff1a;基于资料的数据可视化工具简单介绍&#xff1a;D3.js 与 Canvas绘图12 资料取自《JavaScript高级程序设计&#xff08;第5版&#xff09;》。 查看总目录&#xff1a;红宝书学习大纲 一、D3.js&#xff1a;数据驱动文档的王者 1 核心特性&#x…

深入理解 Vue 的数据代理机制

何为数据代理&#xff1f; 通过一个对象代理对另一个对象中的属性的操作&#xff08;读/写&#xff09;&#xff0c;就是数据代理。 要搞懂Vue数据代理这个概念&#xff0c;那我们就要从Object.defineProperty()入手 Object.defineProperty()是Vue中比较底层的一个方法&…

Java excel导入/导出导致内存溢出问题,以及解决方案

excel导入/导出导致内存溢出问题&#xff0c;以及解决方案 1、内存溢出问题导入功能重新修正&#xff0c;采用SAX的流式解析数据。并结合业务流程。导出功能&#xff1a;由于精细化了业务流程&#xff0c;导致比较代码比较冗杂&#xff0c;就只放出最简单的案例。 1、内存溢出问…

10 个最新 CSS 功能已在所有主流浏览器中得到支持

前言 CSS 不断发展&#xff0c;新功能使我们的工作更快、更简洁、更强大。得益于最新的浏览器改进&#xff08;Baseline 2024&#xff09;&#xff0c;许多新功能现在可在所有主要引擎上使用。以下是您可以立即开始使用的10 CSS新功能。 1. Scrollbar-Gutter 和 Scrollbar-Co…

思科模拟器的单臂路由,交换机,路由器,路由器只要两个端口的话,连接三台电脑该怎么办,划分VLAN,dotlq协议

单臂路由 1. 需求&#xff1a;让三台电脑互通 2. 在二层交换机划分vlan&#xff0c;并加入&#xff1b; 3. 将连接二层交换机和路由器的端口f0/4改为trunk模式 4. 路由器&#xff1a;进入连接路由器的f0/0端口将端口开启 5. 进入每个vlan设dotlq协议并设网络IP&#xff08…

14 nginx 的 dns 缓存的流程

前言 这个是 2020年11月 记录的这个关于 nginx 的 dns 缓存的问题 docker 环境下面 前端A连到后端B 前端B连到后端A 最近从草稿箱发布这个问题的时候, 重新看了一下 发现该问题的记录中仅仅是 定位到了 nginx 这边的 dns 缓存的问题, 但是 并没有到细节, 没有到 具体的 n种…

实战教程:使用JetBrians Rider快速部署与调试PS5和Xbox上的UE项目

面向主机游戏开发者的重大新闻&#xff01;在2024.3版本中&#xff0c;JetBrains Rider 增加了对 PlayStation5 和 Xbox 游戏主机的支持&#xff0c;您可以直接在您喜欢的游戏主机上构建、部署和调试 Unreal Engine 和自定义游戏引擎。 JetBrains Rider现在支持主机游戏开发&am…