Next.js 配置 react-intl 实现语言国际化

栏目: IOS · Android · 发布时间: 5年前

内容简介:使用Next.js的主要目的是实现SSR优化SEO,当然在使用过程中遇到过很多问题。非常感谢luffyZh 分享的文章,让我少走很多弯路。(Tip:刚开始搭建的同学, 建议先去看luffyZh 和官方文档 了解基础知识再来看本文章哦 #^.^# )。言归正传,antd官方是推荐使用react-intl实现国际化的,下面分享一下我在Next.js中实现国际化的过程,有不对或可优化的欢迎指正哦。示例:

使用Next.js的主要目的是实现SSR优化SEO,当然在使用过程中遇到过很多问题。非常感谢luffyZh 分享的文章,让我少走很多弯路。(Tip:刚开始搭建的同学, 建议先去看luffyZh 和官方文档 了解基础知识再来看本文章哦 #^.^# )。

言归正传,antd官方是推荐使用react-intl实现国际化的,下面分享一下我在Next.js中实现国际化的过程,有不对或可优化的欢迎指正哦。

一、npm 加载 react-intl

  • npm i react-intl -S

二、在根目录添加locales文件夹,用于存放不同语言的js文件

示例:

locales/
--| en.js  // 存放语言文本键值对
--| en-US.js // 导出存放语言的对象
--| zh.js  
--| zh-CN.js 
复制代码

zh.js

tip: 对象只能使用"debugObj.hello"这种方式,咱们常用的 debugObj{ hello:'你好' } 在这里使用会导致组件中取不到值

export default {
  title:'标题',
  dynamicName:" 动态赋值:{val}",
  "debugObj.hello":"你好 Debug对象",
};
复制代码

zh-CN.js

import appLocaleData from 'react-intl/locale-data/zh';
import zhMessages from './zh.js';
import antdZh from 'antd/lib/locale-provider/zh_CN'; //antd语言包

let appLocale = {
  messages: {
    ...zhMessages,
  },
  antd: antdZh,
  locale: 'zh-CN',
  data: appLocaleData,
};

export default appLocale;
复制代码

三、在/pages/_app.js中引入LocaleProvide(antd组件语言)和IntlProvider(react-intl)组件,在render函数中包裹根组件。

_app.js

import { Fragment } from 'react';
import App, { Container } from 'next/app';
import { LocaleProvider } from 'antd';
import { addLocaleData, IntlProvider } from 'react-intl';

//导入中英文对象
import _ZH from '../locales/zh-CN'; 
import _EN from '../locales/en-US';

let appLocale = {
  messages: {
    ...zhMessages,
  },
  antd: antdZh,
  locale: 'zh-CN',
  data: appLocaleData,
};


class PageContainer extends App {

  getLocale(languages){
    const appLocale = this.getLocaleDatas(languages);
    addLocaleData(...appLocale.data);
    return appLocale;
  }
  
  getLocaleDatas(lang) {
    let result = {};
    switch (lang) {
      case 'zh-CN':
        result = _ZH;
        break;
      case 'en-US':
        result = _EN;
        break;
      default:
        result = _ZH;
    }
    return result;
  }
  
  // 该render在F5刷新,服务端执行一次后再到前端客户端执行一次
  render () {
    const { Component, pageProps, router } = this.props;
    
    // router.query.lang当前语言 - 需要通过修改server.js传入query.lang
    // 根据url设置语言
    const languages = router.query.lang || 'zh-CN';
    const appLocale = this.getLocale(languages);

    return (
      <Fragment>
        <Container>
            {/* antd语言 */}
            <LocaleProvider locale={appLocale.antd}>
              {/* 引用语言包 */}
              <IntlProvider 
                locale={appLocale.locale}
                messages={appLocale.messages}
                formats={appLocale.formats}
                >
                  <Component {...pageProps} router={router} />
              </IntlProvider>
            </LocaleProvider>
        </Container>
      </Fragment>
    );
  }
}

export default appLocale;
复制代码

四、修改server.js,通过正则匹配URL语言名称,该名称可以在_app.js的render函数中this.props获取

server.js

const express = require('express');
const cp = require('child_process');
const next = require('next');

const PORT = '3006';
const dev = true;

const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare()
  .then(() => {
    const server = express();

    // 处理语言包
    const LangExp = new RegExp(/^(\/zh-CN)|(\/en-US)/i);
    server.get(LangExp, (req, res) => {
      let path = req.path;
      let lang = path.match(LangExp)[0];
      let url = path.replace(lang, '');
      lang = lang.slice(1, lang.length);
      // 跳转默认主页
      if (!url){
        url = `/home`;
      }
      console.log(url, lang, '----------route---');
      return app.render(req, res, url, { lang });
      
    });

    // 重定向默认路径
    server.get('/', (req, res) => {
      res.redirect("/zh-CN/home");
    });
    
    server.get('*', (req, res) => {
      return handle(req, res);
    });

    server.listen(PORT, err => {
      if (err) throw err;
      const serverUrl = `http://localhost:${PORT}`;
      console.log(`> Ready on ${serverUrl}`);
    });
  });


复制代码

五、配置完成后,在组件中使用

home.js

//FormattedMessage编译后是一个span标签
import { Component } from 'react';
import {Button} from 'antd';
import Link from 'next/link';
import { FormattedMessage  } from 'react-intl'; 
export default class Home extends Component {
    constructor(props){
        super(props);
        this.lang = {
          title:{
            id:'title'
          }
        };
     }
    render(){
        return (
          {/* 用法一 */}
          <FormattedMessage id="title"/>
          <br/>
          {/* 对象 */}
          <FormattedMessage id="debugObj.hello"/>
          <br/>
          {/* 动态赋值 */}
          <FormattedMessage id="dynamicName"   values={{val:'888999'}}/>
          <br/>
          {/* 用法二 */}
          <FormattedMessage {...this.lang.title}/>
          <br/>
          
          <br/>
          <br/>
          {/* 语言切换 */}
          <Link href={`/zh-CN/home`}>
            <Button type="primary">中文</Button>
          </Link>

          <Link href={`/en-US/home`}>
            <Button type="primary">English</Button>
          </Link>
        );
    }
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

活着就为改变世界

活着就为改变世界

[美] 杰弗里·扬、威廉·西蒙 / 蒋永军 / 中信出版社 / 2010-6 / 39.00元

内容简介 苹果公司CEO史蒂夫•乔布斯这个一直活在自己想象的世界里的创业奇才,经历过各种挫折与失落,但他那无所畏惧、敢于承担的个性让他一直努力实践着自己的价值观,总能为他的离奇想法找到解决问题的办法。 本书两位作者通过深入访谈和资料调查,揭秘了许多乔布斯个人的创业经历和家庭变故,为大家塑造了一个活生生的“乔布斯式”的鲜活人物,描述了一个个充满传奇色彩的商业奇迹,真实地再现了乔布斯几十年......一起来看看 《活着就为改变世界》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试