转到国际项目组之后,做的项目都是多语言的,上次的项目是用vue
搭建的,所以使用的是vue-i18n
这个插件,具体可以看这:vue3实现国际化
这次的项目是用react
搭建的,也顺手整理一下
技术栈:Hooks + vite + antd + recoil
多语言插件使用的是i18next
需要同时安装两个包
$ npm install react-i18next i18next --save
// or
$ yarn add react-i18next i18next --save
在src下新建locals文件夹,包含index.js
,en.js
,zh.js
(只做中英文切换)
// zh.js
export default {
login: {
login: '登录',
userName: '用户名',
password: '密码',
tips: '你好 {{name}}!'
}
}
// en.js
export default {
login: {
login: 'login',
userName: 'userName',
password: 'password',
tips: 'hello {{name}}!'
}
}
// index.js
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import en from './en'
import zh from './zh'
const resources = {
en: {
translation: en
},
zh: {
translation: zh
}
}
i18n.use(initReactI18next).init({
resources,
lng: localStorage.getItem('lang') || 'en',
fallbackLng: 'en',
interpolation: {
escapeValue: false
}
})
export default i18n
有个注意的地方就是上面用了缓存,待会会说到为什么要这样做
最后在main.js
引入就好了(这里比vue简单些)
import '@/locals'
至此插件就算配置好了
对比vue,在react中使用比较简单,只需要用到t
方法即可,有两种方式可以使用
useTranslation
钩子import { useTranslation } from 'react-i18next'
const Index = () => {
const { t } = useTranslation()
return(
<div>{t('login.useName')}</div>
<div>{t('login.tips',{name:'Tony'})}</div>{/* 你好 Tony! */}
)
}
i18next
中引入import { t } from 'i18next'
const Index = () => {
return(
<div>{t('login.useName')}</div>
<div>{t('login.tips',{name:'Tony'})}</div>{/* 你好 Tony! */}
)
}
关于t()
还有很多用法,具体还是去官网看看
需要用到useTranslation
钩子
import { useTranslation } from 'react-i18next'
import { Menu, Dropdown, Space } from 'antd'
const Index = () => {
const { t, i18n } = useTranslation()
const changeLang = (lang) => {
i18n.changeLanguage(lang)
localStorage.setItem('lang', lang)
}
const menu = (
<Menu selectable defaultSelectedKeys={[user.lang]}>
<Menu.Item key="en" onClick={() => changeLang('en')}>
English
</Menu.Item>
<Menu.Item key="zh" onClick={() => changeLang('zh')}>
中文
</Menu.Item>
</Menu>
)
return (
<div className="header">
<div className="flex-end">
<Dropdown overlay={menu} arrow>
<a onClick={(e) => e.preventDefault()}>
<Space>
{t('language')}
<DownOutlined />
</Space>
</a>
</Dropdown>
</div>
</div>
)
}
export default Index
问题其实也是跟之前用vue3+vue-i18n的时候一样,就是刷新后语言又重置了,所以解决办法也是一样,设置缓存就好了
antd
也是支持多语言的,可以使用ConfigProvider动态切换,在App.jsx
里面配置
// App.jsx
import React, { Suspense, useState } from 'react'
import { BrowserRouter} from 'react-router-dom'
import Routers from './router'
import './App.css'
import { ConfigProvider } from 'antd'
import zhCN from 'antd/es/locale/zh_CN'
import enUS from 'antd/lib/locale/en_US'
import { useRecoilState } from 'recoil'
import { userState } from '@/store/user'
function App() {
//!! 因为我这个项目是使用recoil全局保存语言的。 你们要根据自己的项目情况修改
const [user, setUser] = useRecoilState(userState)
const { lang } = user
const getLanguage = () => {
if (lang === 'en') return enUS
if (lang === 'zh') return zhCN
}
return (
<ConfigProvider locale={getLanguage()}>
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routers />
</Suspense>
</BrowserRouter>
</ConfigProvider>
)
}
export default App
最后附上我们项目的地址参考 http://egypt.agogopost.com/
完事