next-i18next 用於next.js 項目的插件html
next-i18next 底層使用的是 i18next 和 react-i18next,須要react和 next 的支持react
默認狀況下,next-i18next 中對應的JSON 文件的路徑方式以下: 只須要將翻譯內容整理到JSON文件中json
└── static └── locales ├── en | └── common.json └── de └── common.json數組
引入高階組件 import { withNamespaces } from 'i18n';安全
使用: (withNamespaces('moduleDemo')(TradeForm)) 調用的時候須要將json文件和組件進行包裹,這樣會返回高階組件處理以後的組件bash
moduleDemo 爲提取的變量,後面的參數是組件app
moduleDemo 爲 json 文件名稱,裏面的是頁面中的各個變量less
withNamespaces 這個高階組件負責將 函數 t 傳給組件,它支持i18next提供的全部翻譯功能。 在調用withNamespaces 這個高階組件的時候,其實就至關於給組件注入了一個函數 t,在返回的組件中就可使用這個函數 t。async
而後在組件中就可使用函數 t 對對應的變量進行翻譯,json文件中的變量和組件中的變量一一對應函數
在json文件中提取的變量最好不要有:,.這樣的特殊內容,不然解析會出錯。
在action中使用:由於在action中有對應的一些提示性的內容,這樣就須要提取: action爲單獨js文件
引入: import { i18n } from 'i18n';
調用庫裏面的方法,返回對應的函數 t: const t = i18n.getFixedT(i18n.language, 'common');
目前action中的變量提取到 common.json 文件中 以後就能夠調用 t 方法來進行翻譯
在這裏有兩個變量: {{min}} {{currency}}
一樣在json變量文件中也須要一樣的變量 "Amount can not be less than the minimum {{min}} {{currency}}": "Amount can not be less than the minimum {{min}} {{currency}}",
在react中使用就須要用 dangerouslySetInnerHTML 這樣的方式來使用:
由於這樣會將數據動態的插入到頁面中,這樣的話,就會涉及到安全性的問題。 這個在React中是不容許的。
<span
className={classNames(classes.contentRoot)}
dangerouslySetInnerHTML={{
__html: t('termsContent'),
}}
/>
複製代碼
項目中的配置及讀取的方式:
const NextI18Next = require('next-i18next/dist/commonjs').default;
module.exports = new NextI18Next({
defaultLanguage: 'en',
debug: false,
otherLanguages: ['zh'],
// localeSubpaths: 'foreign',
localeSubpaths: 'all',
// localePath: `${isBrowser() ? '' : 'app/'}static/locales`,
localePath: 'app/static/locales',
});
複製代碼
獲取i18n對象後,構造一個配置內容,好比默認的語言 localePath 這個配置指定本地語言包的路徑: app/static/locales/en app/static/locales/zh 之後若是要新增新的語言包就是這樣的路徑
項目中server.js中引入了這個配置,並經過中間件的形式調用這個配置
const nextI18NextMiddleware = require('next-i18next/middleware');
const nextI18next = require('./app/i18n');
server.use(nextI18NextMiddleware(nextI18next));
複製代碼
高階組件是一個函數,接收一個組件並返回一個新的組件,這也就意味着,高階組件能夠實現
經過包裹原來的組件來操做props,好比咱們接收一個組件,同時原封不動的返回這個組件原來的樣式,只是對接收組件的props屬性進行操做,這樣返回的新的組件中就有了新的props 固然操做props只是一個方面,另外能夠將被包裹的組件的狀態提取到包裹組件中,從而完成組件狀態的抽象,好比能夠實現將非受控組件轉變成受控組件。
函數t的主要功能是什麼?是怎麼找到對應的文件中對應的變量的?如何根據語言去選擇哪一種變量呢?
在 next-i18next 文檔中能夠看出,next-i18next 組件底層依賴 react-i18next: import { Trans } from 'react-i18next'
而 react-i18next 中對這塊代碼的實現爲函數:useTranslation,而這裏採用了React最新特性:React Hooks
每一個頁面加載的數據並非不少,因此對應的語言包文件中的內容也不會特別的多,
而頁面加載時須要對語言包文件進行load,若是加載全部的語言包的話,就會很是耗時,這是不可取的。
在加載組件時,做爲頁面的頂層組件中去獲取數據的時候,在next-i18next 中,默認狀況下會在初始請求時將全部名稱空間發送到客戶端,因此默認有個配置:
在配合next.js時,須要經過頁面級組件上的getInitialProps返回namespacesRequired數組。
import React from 'react';
class Home extends React.Component {
static async getInitialProps() {
return {
namespacesRequired: ['common', 'footer']
}
}
}
複製代碼