美文网首页IT技术篇
React + umi(使用umi内部组件SelectLang)

React + umi(使用umi内部组件SelectLang)

作者: 燕自浩 | 来源:发表于2022-11-18 22:43 被阅读0次

    前言:众所周知项目国际化首先会想到的是有英文,其次就是我们开发者所在地的语言比如我们的中文,那么如果想要添加一个其他国家的语言该怎么办?还是第一次接触添加其他国家的语言,直接想法是一个下拉框里面添加你想要的国家然后根据下拉的value值进行切换对应的国际化的文件。我们拿React + Umi通过解析源码来记录一下

    首先我们找到Umi的国际化切换组件SelectLang发现这并不直接是一个下拉框,那么我们初始的构想在里面加一个选项的想法就被迫落空,下面看下代码

    Umi提供的切换语言的组件
    <SelectLang />

    按着Ctrl点击组件名可以看到该组建所接受的Props就有哪些下面列一下

    组件的Props属性有
    globalIconClassName?: string;
    postLocalesData?: (locales: LocalData[]) => LocalData[];
    onItemClick?: (params: ClickParam) => void;
    className?: string;
    reload?: boolean;
    icon?: React.ReactNode;
    

    可以看到onItemClick是切换国际化的回调函数,参数是所切换成的语言的value值,我们可以看到里面并没有类似于SelectOptions属性,那么我们如果添加我们想要的国际化语言
    通过按Ctrl同时用鼠标点击SelectLang标签会进入到源码,也就是SelectLang.tsx文件

    const langMenu = (
        <Menu selectedKeys={[selectedLang]} onClick={handleClick}>
          {allLangUIConfig.map((localeObj) => {
            return (
              <Menu.Item key={localeObj.lang || localeObj.key} style={menuItemStyle}>
                <span role="img" aria-label={localeObj?.label || "en-US"} style={menuItemIconStyle}>
                  {localeObj?.icon || "🌐"}
                </span>
                {localeObj?.label || "en-US"}
              </Menu.Item>
            );
          })}
        </Menu>
      );
    

    这个就是组件源码下拉的渲染部分,我们可以看到是通过allLangUIConfig负责渲染我们想要的语言,那么allLangUIConfig的来源是什么呢,我们接着往下看,通过查找发现还是在源码中发现

      const allLangUIConfig =
        postLocalesData?.(defaultLangUConfig) || defaultLangUConfig;
      const handleClick = onItemClick
        ? (params: ClickParam) => onItemClick(params)
        : changeLang;
    

    我们此时又看到了postLocalesData,这个不是组件SelectLangProps吗?没错就是这样的,这个组件接收一个LocalData类型的数组

    interface LocalData {
        lang: string,
        label?: string,
        icon?: string,
        title?: string,
    }
    

    等等我们可以看到allLangUIConfig =postLocalesData?.(defaultLangUConfig) || defaultLangUConfig如果我们不传postLocalesData这个Props那么怎么实现呢,我们再来看下defaultLangUConfig的来源是什么

      const defaultLangUConfig = getAllLocales().map(
        (key) =>
          defaultLangUConfigMap[key] || {
            lang: key,
            label: key,
            icon: "🌐",
            title: key,
          }
      );
    

    我们不止看到了defaultLangUConfigMap又看到了getAllLocales,像不像套娃一个接一个哈哈,那么我们一层一层的看,先来看一下getAllLocales,发现getAllLocales的来源是

    import { getLocale, getAllLocales, setLocale } from './localeExports';
    

    那么localeExports里面是什么呢,我们一起来看下

    export const localeInfo: {[key: string]: any} = {
      'en-US': {
        messages: {
          ...lang_enUS0,
        },
        locale: 'en-US',
        antd: {
          ...enUS0,
        },
        momentLocale: '',
      },
      'th-TH': {
        messages: {
          ...lang_thTH0,
        },
        locale: 'th-TH',
        antd: {
          ...thTH0,
        },
        momentLocale: 'th',
      },
      'zh-CN': {
        messages: {
          ...lang_zhCN0,
        },
        locale: 'zh-CN',
        antd: {
          ...zhCN0,
        },
        momentLocale: 'zh-cn',
      },
    };
    /**
     * 获取语言列表
     * @returns string[]
     */
    export const getAllLocales = () => Object.keys(localeInfo);
    

    比如我们需要日本的语言,localeInfo里面的信息不需要我们人为的添加,只需要在defaultLangUConfigMap中找到日本所对应的key,日本对应的语言的key就是ja-JP,我们只需在我们的项目中找到locales这个文件夹在里面新建一个文件夹叫做ja-JP,里面放日本的语言文件,然后再建一个ja-JP.ts来引入文件夹ja-JP下面的文件即可
    接着看下defaultLangUConfigMap,胜利就在眼前了撑住兄弟们

    const defaultLangUConfigMap = {
      'ar-EG': {
        lang: 'ar-EG',
        label: 'العربية',
        icon: '🇪🇬',
        title: 'لغة'
      },
      'az-AZ': {
        lang: 'az-AZ',
        label: 'Azərbaycan dili',
        icon: '🇦🇿',
        title: 'Dil'
      },
      'bg-BG': {
        lang: 'bg-BG',
        label: 'Български език',
        icon: '🇧🇬',
        title: 'език'
      },
      'bn-BD': {
        lang: 'bn-BD',
        label: 'বাংলা',
        icon: '🇧🇩',
        title: 'ভাষা'
      },
      'ca-ES': {
        lang: 'ca-ES',
        label: 'Catalá',
        icon: '🇨🇦',
        title: 'llengua'
      },
      'cs-CZ': {
        lang: 'cs-CZ',
        label: 'Čeština',
        icon: '🇨🇿',
        title: 'Jazyk'
      },
      'da-DK': {
        lang: 'da-DK',
        label: 'Dansk',
        icon: '🇩🇰',
        title: 'Sprog'
      },
      'de-DE': {
        lang: 'de-DE',
        label: 'Deutsch',
        icon: '🇩🇪',
        title: 'Sprache'
      },
      'el-GR': {
        lang: 'el-GR',
        label: 'Ελληνικά',
        icon: '🇬🇷',
        title: 'Γλώσσα'
      },
      'en-GB': {
        lang: 'en-GB',
        label: 'English',
        icon: '🇬🇧',
        title: 'Language'
      },
      'en-US': {
        lang: 'en-US',
        label: 'English',
        icon: '🇺🇸',
        title: 'Language'
      },
      'es-ES': {
        lang: 'es-ES',
        label: 'Español',
        icon: '🇪🇸',
        title: 'Idioma'
      },
      'et-EE': {
        lang: 'et-EE',
        label: 'Eesti',
        icon: '🇪🇪',
        title: 'Keel'
      },
      'fa-IR': {
        lang: 'fa-IR',
        label: 'فارسی',
        icon: '🇮🇷',
        title: 'زبان'
      },
      'fi-FI': {
        lang: 'fi-FI',
        label: 'Suomi',
        icon: '🇫🇮',
        title: 'Kieli'
      },
      'fr-BE': {
        lang: 'fr-BE',
        label: 'Français',
        icon: '🇧🇪',
        title: 'Langue'
      },
      'fr-FR': {
        lang: 'fr-FR',
        label: 'Français',
        icon: '🇫🇷',
        title: 'Langue'
      },
      'ga-IE': {
        lang: 'ga-IE',
        label: 'Gaeilge',
        icon: '🇮🇪',
        title: 'Teanga'
      },
      'he-IL': {
        lang: 'he-IL',
        label: 'עברית',
        icon: '🇮🇱',
        title: 'שפה'
      },
      'hi-IN': {
        lang: 'hi-IN',
        label: 'हिन्दी, हिंदी',
        icon: '🇮🇳',
        title: 'भाषा: हिन्दी'
      },
      'hr-HR': {
        lang: 'hr-HR',
        label: 'Hrvatski jezik',
        icon: '🇭🇷',
        title: 'Jezik'
      },
      'hu-HU': {
        lang: 'hu-HU',
        label: 'Magyar',
        icon: '🇭🇺',
        title: 'Nyelv'
      },
      'hy-AM': {
        lang: 'hu-HU',
        label: 'Հայերեն',
        icon: '🇦🇲',
        title: 'Լեզու'
      },
      'id-ID': {
        lang: 'id-ID',
        label: 'Bahasa Indonesia',
        icon: '🇮🇩',
        title: 'Bahasa'
      },
      'it-IT': {
        lang: 'it-IT',
        label: 'Italiano',
        icon: '🇮🇹',
        title: 'Linguaggio'
      },
      'is-IS': {
        lang: 'is-IS',
        label: 'Íslenska',
        icon: '🇮🇸',
        title: 'Tungumál'
      },
      'ja-JP': {
        lang: 'ja-JP',
        label: '日本語',
        icon: '🇯🇵',
        title: '言語'
      },
      'ku-IQ': {
        lang: 'ku-IQ',
        label: 'کوردی',
        icon: '🇮🇶',
        title: 'Ziman'
      },
      'kn-IN': {
        lang: 'zh-TW',
        label: 'ಕನ್ನಡ',
        icon: '🇮🇳',
        title: 'ಭಾಷೆ'
      },
      'ko-KR': {
        lang: 'ko-KR',
        label: '한국어',
        icon: '🇰🇷',
        title: '언어'
      },
      'lv-LV': {
        lang: 'lv-LV',
        label: 'Latviešu valoda',
        icon: '🇱🇮',
        title: 'Kalba'
      },
      'mk-MK': {
        lang: 'mk-MK',
        label: 'македонски јазик',
        icon: '🇲🇰',
        title: 'Јазик'
      },
      'mn-MN': {
        lang: 'mn-MN',
        label: 'Монгол хэл',
        icon: '🇲🇳',
        title: 'Хэл'
      },
      'ms-MY': {
        lang: 'ms-MY',
        label: 'بهاس ملايو',
        icon: '🇲🇾',
        title: 'Bahasa'
      },
      'nb-NO': {
        lang: 'nb-NO',
        label: 'Norsk',
        icon: '🇳🇴',
        title: 'Språk'
      },
      'ne-NP': {
        lang: 'ne-NP',
        label: 'नेपाली',
        icon: '🇳🇵',
        title: 'भाषा'
      },
      'nl-BE': {
        lang: 'nl-BE',
        label: 'Vlaams',
        icon: '🇧🇪',
        title: 'Taal'
      },
      'nl-NL': {
        lang: 'nl-NL',
        label: 'Vlaams',
        icon: '🇳🇱',
        title: 'Taal'
      },
      'pl-PL': {
        lang: 'pl-PL',
        label: 'Polski',
        icon: '🇵🇱',
        title: 'Język'
      },
      'pt-BR': {
        lang: 'pt-BR',
        label: 'Português',
        icon: '🇧🇷',
        title: 'Idiomas'
      },
      'pt-PT': {
        lang: 'pt-PT',
        label: 'Português',
        icon: '🇵🇹',
        title: 'Idiomas'
      },
      'ro-RO': {
        lang: 'ro-RO',
        label: 'Română',
        icon: '🇷🇴',
        title: 'Limba'
      },
      'ru-RU': {
        lang: 'ru-RU',
        label: 'Русский',
        icon: '🇷🇺',
        title: 'язык'
      },
      'sk-SK': {
        lang: 'sk-SK',
        label: 'Slovenčina',
        icon: '🇸🇰',
        title: 'Jazyk'
      },
      'sr-RS': {
        lang: 'sr-RS',
        label: 'српски језик',
        icon: '🇸🇷',
        title: 'Језик'
      },
      'sl-SI': {
        lang: 'sl-SI',
        label: 'Slovenščina',
        icon: '🇸🇱',
        title: 'Jezik'
      },
      'sv-SE': {
        lang: 'sv-SE',
        label: 'Svenska',
        icon: '🇸🇪',
        title: 'Språk'
      },
      'ta-IN': {
        lang: 'ta-IN',
        label: 'தமிழ்',
        icon: '🇮🇳',
        title: 'மொழி'
      },
      'th-TH': {
        lang: 'th-TH',
        label: 'ไทย',
        icon: '🇹🇭',
        title: 'ภาษา'
      },
      'tr-TR': {
        lang: 'tr-TR',
        label: 'Türkçe',
        icon: '🇹🇷',
        title: 'Dil'
      },
      'uk-UA': {
        lang: 'uk-UA',
        label: 'Українська',
        icon: '🇺🇰',
        title: 'Мова'
      },
      'vi-VN': {
        lang: 'vi-VN',
        label: 'Tiếng Việt',
        icon: '🇻🇳',
        title: 'Ngôn ngữ'
      },
      'zh-CN': {
        lang: 'zh-CN',
        label: '简体中文',
        icon: '🇨🇳',
        title: '语言'
      },
      'zh-TW': {
        lang: 'zh-TW',
        label: '繁體中文',
        icon: '🇭🇰',
        title: '語言'
      }
    };
    

    可以看到defaultLangUConfigMap这个信息还是非常全面的几乎覆盖所有的国家,
    最后拿着getAllLocales获取的所有的配置信息在defaultLangUConfigMap中挑出对应的配置来给国际语言切换组件SelectLangMenu来渲染,这样我们就不用postLocalesData这个属性就可以实现我们想要的功能

    本篇文章到这里就结束了感谢看我啰嗦 哈哈

    相关文章

      网友评论

        本文标题:React + umi(使用umi内部组件SelectLang)

        本文链接:https://www.haomeiwen.com/subject/lyvpxdtx.html