国际化语言,多语言三种方式

news2025/7/10 23:50:20
  1. 可以用透传的方式,自己写local的json文件,不需要配置什么,直接传,自己写方法

  1. i18n nextjs

  1. i18n umi4

一、透传的方式 export const AppContext = React.createContext<any>({})

  1. app.tsx 用context包裹

import type { AppProps } from 'next/app'
import React, { useState } from 'react';
import { appWithTranslation } from 'next-i18next'

import enUs from '../public/locales/EN/common.json';
import zhCN from '../public/locales/ZH_CN/common.json';

export const AppContext = React.createContext<any>({})
const App = ({ Component, pageProps }: AppProps) => {
  const [locale, setLocal] = useState(zhCN);

  return <AppContext.Provider value={{locale,setLocal}} >
    <Component {...pageProps} />
  </AppContext.Provider>
}
export default appWithTranslation(App)
  1. 写local.json文件

//中文

{
    "welcome": "欢迎"
}

//英文

{
    "welcome": "welcome"
}
  1. 封装方法

import { useContext } from "react";
import { AppContext } from "../pages/_app";


const useLocale = () => {
    const { locale } = useContext(AppContext);
    const getLocale = (key: string) => {
        if (!key) throw new Error(`key is not defined`);
        const keys = key.split('.');
        let nowValue = locale;
        let res = null;
        try {
            keys.forEach((item, index) => {
                const subItem = nowValue[item];
                if (index === keys.length - 1) {
                    res = subItem;
                } else {
                    if (typeof subItem === 'object' && subItem !== null) {
                        nowValue = subItem;
                    } else {
                        res = null;
                       console.log(res)
                    }
                }
            });
        } catch (err) {
            console.log(err)
        }
        return res;
    }
    return getLocale;
}

export default useLocale;

  1. 使用:

  const Home = (props:any) => {
  const { setLocal } = useContext(AppContext);
  const getLocale = useLocale();

// 语言切换
  const handleLanguageChange = (value: string) => {
    if(value==='EN'){
      setLocal(enUs)
    }
    if(value==='ZH_CN'){
      setLocal(zhCN)
    }
  };
return({
<>
<p> { getLocale('welcome')}</p>  //应用

<div className={styles.selectBtn}>
                  <Select
                    defaultValue="ZH_CN"
                    onChange={handleLanguageChange}
                    getPopupContainer={() => document.getElementById('area') !}
                    options={[
                      { value: "EN", label: "英文" },
                      { value: "ZH_CN", label: "中文" },
                    ]}
                  />
                </div>

}
</>
})

二、场景二:next.js下载配置

npm install next-i18next
  1. 根目录下新建文件 next-i18next.config.js

module.exports = {
  i18n: {
    defaultLocale: "en",
    locales: ["en",  "zh-CN"],
    localePath: "./locales",
  },
};
  1. next.config.js

const { i18n } = require("./next-i18next.config");

const nextConfig = {
  // other stuff
  i18n,
};

module.exports = nextConfig;
  1. local文件夹,文件夹在public下面新建locales

.
└── locales
    ├── en
    |   └── common.json
    |   └── home.json
    └── zh-CH
    |   └── common.json
    |   └── home.json
    
  1. 高阶组件引用:pages/_app.jsx

import { appWithTranslation } from "next-i18next";
import Header from "../components/Header";
import "../styles/globals.css";

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Header />
      <Component {...pageProps} />
    </>
  );
}

export default appWithTranslation(MyApp);
  1. index.tsx文件里面使用 pages/index.jsx

import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { useRouter } from "next/router";

// export default function Home...
  const { route, asPath, push } = useRouter();

// 语言切换
  const handleLanguageChange = (value: string) => {

     push(route, asPath, {
      locale: value as any
     })
  };

 <div className={styles.selectBtn}>
                  <Select
                    defaultValue="ZH_CN"
                    onChange={handleLanguageChange}
                    getPopupContainer={() => document.getElementById('area') !}
                    options={[
                      { value: "EN", label: "英文" },
                      { value: "ZH_CN", label: "中文" },
                    ]}
                  />
                </div>


export async function getStaticProps({ locale }) {
  return {
    props: {
      ...(await serverSideTranslations(locale, ["common", "home"])),
      // Will be passed to the page component as props
    },
  };
}
  1. pages/index.jsx

// other imports
import { useTranslation } from "next-i18next";

export default function Home() {
  // We want to get the translations from `home.json`
  const { t } = useTranslation("home");

  // Get the translation for `greeting` key
  return <main>{t("welcome")}</main>;
}

// export async function getStaticProps...

此处:nextjs的多语言就能使用了

如果我们希望它使用默认的语言环境值(在我们的例子中是en),我们可以省略一些翻译键。

还有个例子可以参考:

{
  "title": "保持最新状态",
  "form": {
    "email": "电子邮箱",
    "action": {
      "cancel": "取消"
    }
  }
}
import { useTranslation } from "next-i18next";
import React from "react";

const SubscribeForm = () => {
  const { t } = useTranslation("newsletter");

  return (
    <section>
      <h3>{t("title")}</h3>
      <h4>{t("subtitle")}</h4>

      <form>
        <input placeholder={t("form.firstName")} />
        <input placeholder={t("form.email")} />
        <button>{t("form.action.signUp")}</button>
        <button>{t("form.action.cancel")}</button>
      </form>

      {/* For styling only */}
      <style jsx>{`
        form {
          max-width: 300px;
          display: flex;
          flex-direction: column;
        }

        input {
          margin-bottom: 0.5rem;
        }
      `}</style>
    </section>
  );
};

export default SubscribeForm;

next 如果只打包静态页面,i18n会报错,可以用第一种透传的方式。

三、场景三:umi里面的多语言i18n

  1. index.tsx

import { SelectLang } from '@umijs/max';

 <SelectLang className={styless.action} />
  1. locales.js和前面一样{ },如果是locales.ts的话,注意export default暴露这样写:

export default{
"welcome":"welcome"
}
  1. umirc.ts

import { defineConfig } from '@umijs/max';
import routes from './src/routes/index';
import proxy from './config/proxy';
const { APP_ENV } = process.env;

export default defineConfig({
  history: { type: 'hash' },
  dva: {},
  antd: {},
  access: {},
  model: {},
  initialState: {},
  request: {},
  locale: {
    antd: true, // 如果项目依赖中包含 `antd`,则默认为 true  一定要设置 否则SelectLang不显示
    baseNavigator: true,
    baseSeparator: '-',
    default: 'zh-CN',
    title: false,
    useLocalStorage: true,
  },
  ignoreMomentLocale: true,
  
  // Option+Click/Alt+Click 点击组件跳转至编辑器源码位置
  clickToComponent: { editor: 'vscode' },
});
  1. 封装hooks

import { getIntl } from "@umijs/max";

let intl = getIntl ();

function useLocale(name:string,values?:{[key:string]:any}):string{

    if(!name)return '';
    return intl.formatMessage({
      id:name
    },{...values})|| name;
}

export default useLocale;
  1. index.tsx

<div> {useLocale('welcome')}</div>

如果没有封装hook,可以使用 FormattedMessage ,index.tsx里:

import { FormattedMessage, useIntl } from '@umijs/max';

const Home = ()=>{
  const { formatMessage } = useIntl();
return({
     <p>{formatMessage({ id: 'welcome' })}</p>

})

}

ok,三种解决国际化多语言的方式。

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

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

相关文章

如何通过自己编写Jmeter函数

在Jmeter的函数助手里&#xff0c;有很多内置的函数&#xff0c;比如Random、UUID、time等等。使用这些函数可以快速帮我们生成某些数据&#xff0c;进行一些逻辑处理。用起来非常的方便。 但是在实际接口测试过程中&#xff0c;有很多的需求&#xff0c;Jmeter内置的函数可能…

【自制开发板】自制STM32F407开发板(含TFT 8080串口屏幕接口)

【2023 年 2 月 14 日】 许久没有更新&#xff0c;最近做了个小开发板玩了玩。更新一下吧&#xff0c;作为记录&#xff01;&#xff01; 主要是象试一下LVGL在STM32上的应用&#xff0c;所以开发板的大小都是基于屏幕大小来设计的。 分享出来&#xff0c;给大家一个板子结构…

SpringBoot Mybatis 分页实战

pageInfo的属性 pageNum&#xff1a;当前页 pageSize&#xff1a;页面数据量 startRow&#xff1a;当前页首条数据为总数据的第几条 endRow&#xff1a;当前页最后一条数据为总数据的第几条 total&#xff1a;总数据量 pages&#xff1a;总页面数 listPage{}结果集 reasonable …

ESP-C3入门8. 连接WiFi并打印信息

ESP-C3入门8. 连接WiFi并打印信息一、ESP32 连接WiFi的基本操作流程1. 初始化nvs存储2. 配置WiFi工作模式3. 设置WiFi登陆信息4. 启动WiFi5. 开启连接6. 判断是否成功二、事件处理函数1. 定义事件处理函数2. 创建事件组3. 在事件处理函数中设置事件组位4. 在其他任务中等待事件…

基于Selenium+Python的web自动化测试框架

一、什么是Selenium&#xff1f; Selenium是一个基于浏览器的自动化测试工具&#xff0c;它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分&#xff1a;Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE&#xff1a;Firefo…

【安全】Nginx负载均衡下上传Webshell

目录 负载均衡下上传webshell webshell简介 一、环境搭建 ①下载中国蚁剑&#xff0c;于github获取官方版&#xff1a; ②下载docker&docker-compose ③结合前面启动环境 ④验证 Ⅱ、负载均衡下webshell上传的几个问题 ①shell文件上传稳定节点问题 ②命令执行时的…

Windows CMD常用命令

目录 【打开CMD命令】 【网络测试命令】 ipconfig------查看本机网卡信息 ping------测试网络是否通畅 tracert------追踪路由&#xff0c;也可以用来查看网络连通性 telnet------查看目的主机ip的端口号是否开放 tcping------查看目的主机ip的端口号是否开放 【关于路…

【零基础入门前端系列】—无序列表、有序列表、定义列表(四)

一、HTML无序列表 无序列表是一个项目的列表&#xff0c;此列项目使用粗体圆点&#xff08;典型的小黑圆圈&#xff09;进行标记。 无序列表使用 <ul> 标签 <ul> <li>Coffee</li> <li>Milk</li> </ul>嵌套结构&#xff1a; <…

VSCode 的下载安装及基本使用

目录 一、VSCode 是什么&#xff1f; 二、VSCode 的下载和安装 2.1 - 下载 2.2 - 安装 2.3 - 安装汉化插件 三、MinGW-w64 的下载安装及配置 3.1 - 介绍 3.2 - 下载 3.3 - 解压安装 3.4 - 环境变量配置 3.5 - 验证配置是否成功 3.6 - 安装 C/C 插件 四、在 VSCode …

SD卡里的视频无法正常播放出来怎么办?

在日常工作和学习中经常会用到SD卡这个存储设备&#xff0c;它存储空间大&#xff0c;使用方便&#xff0c;很多设备上都使用SD卡作为存储工具。SD卡已经成为我们众多电子设备中重要的一员&#xff0c;为我们存储着相片、视频、文档、音频等数据。 SD卡为我们提供了巨大便利&a…

QT(51)-动态链接库-windows

1.qt- 调用win32 DLL 2.qt- 调用MFC DLL 0概述&#xff1a; 01.扩展DLL&#xff1a; 必须有一个DllMain()函数&#xff0c;且调用AfxInitExtensionModule()函数。 CRuntimeClass类-初始化函数CDynLinkLibrary。02.windows定位DLL文件&#xff1a; 1&#xff09…

第五章 在React中如何定义组件

一、安装react开发者工具 在开始之前&#xff0c;我们先做准备一下辅助工具&#xff0c;类似于Vue的开发者工具&#xff0c;React 开发者工具是一款浏览器扩展&#xff0c;可以帮助您在浏览器中调试 React 应用程序。 下面是如何安装 React 开发者工具的步骤&#xff1a; 打开…

常用类详解(三)StringBuilder

(1)一个可爱的字符序列。此类提供一个与StringBuffer兼容的API&#xff0c;但不保证同步(StringBuilder不是线程安全的)&#xff0c;该类被设计用作StringBuffer的一个简易替换&#xff0c;用在字符串缓冲区被单个线程使用的时候。如果可能&#xff0c;建议优先采用该类&#x…

保护品牌线上声誉的5种方法

我们如今生活在一个搜索便捷的世界&#xff0c;对于一个企业和个人来说&#xff0c;品牌的线上声誉也尤为重要。在客户考虑与您的公司开展业务之前&#xff0c;他们理所当然会先使用众多软件和平台搜索相关信息&#xff0c;以帮助他们了解和做决定。 因此&#xff0c;您的品牌…

2023最新整理软件测试面试题附答案

包含的模块&#xff1a; 本文分为十九个模块&#xff0c;分别是&#xff1a;软件测试 基础、liunx、MySQL、web测试、接口测试、APP测试 、管理工具、Python、性能测试、selenium、lordrunner、计算机网络、组成原理、数据结构与算法、逻辑题、人力资源需要的可以找我获取&…

预算砍砍砍,IT运维如何降本增效

疫情短暂过去&#xff0c;一个乐观的共识正在蔓延&#xff1a;2023年的互联网&#xff0c;绝对不会比2022年更差。 “降本”是过去一年许多公司的核心策略&#xff0c;营销大幅缩水、亏损业务大量撤裁&#xff0c;以及层出不穷的裁员消息。而2023年在可预期的经济复苏下&#…

ChatGPT走红| 微软ATP带你开启高校AI人才培育新时代

与传统搜索引擎不同的是&#xff0c;ChatGPT不是机械罗列出相关网页结果&#xff0c;而是将答案进行整理、优化&#xff0c;以对话形式呈现给用户&#xff0c;还能很快根据上下文互动&#xff01;甚至有人用它辅助自己写论文、完成文字性作业……▍抢跑早规划 入门AI不迷茫AI体…

【C++】类和对象(三)

目录 一、构造函数补充 1、初始化列表 1.1、初始化列表概念 1.2、初始化列表性质 2、explicit关键字 二、static成员 1、概念及使用 2、性质总结 三、友元 1、友元函数 2、友元类 四、内部类 五、拷贝对象时的一些编译器优化 一、构造函数补充 在《类和对象&#x…

GeoTools:FeatureShapefile之CRUD操作

之前在《GIS开源框架&#xff1a;ArcGIS文件地理数据库(GDB)解析与入库》中&#xff0c;从地理数据库的角度对Feature要素进行了解释&#xff0c;接下来&#xff0c;我们将从GeoTools库的角度&#xff0c;重新认识Feature要素&#xff0c;并通过GeoTools实现Shapefile文件在Fea…

产品、技术:如何编写有效的流程文档?

流程文档是指一系列的、连续的、有规律的活动过程&#xff0c;而这些活动以特定的方式进行&#xff0c;并导致特定结果&#xff08;创造价值&#xff09;的产生。流程梳理是指围绕企业的内部要素与外部要素&#xff0c;对整个企业的业务特点和现状进行深入细致的分析、整理、提…