diff --git a/README.md b/README.md index 3ccd3ee..4fc5bed 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ npm i --save @kne/react-intl 技术亮点在于提供了多种创建方式,createIntlProvider 用于创建完整的国际化上下文,createWithIntlProvider 可以为单个组件注入国际化能力,createIntl 则适用于非组件环境的国际化场景。消息加载器支持单个和批量加载,命名空间机制确保不同模块的翻译内容互不干扰。 +***远程加载语言包*** + +远程加载语言包功能支持通过 API 动态获取翻译内容,当本地缺少某语言的翻译时自动触发远程请求。提供智能缓存机制,避免重复请求相同的语言包,适用于按需加载、动态扩展语言支持、分包优化等场景。开发者可通过配置全局上下文的 localeMessage 接口,灵活集成后端翻译服务,实现运营人员动态管理翻译内容,无需重新部署应用。 ### 示例 @@ -40,8 +43,8 @@ npm i --save @kne/react-intl #### 示例代码 -- 基础国际化 -- 使用createIntlProvider创建国际化Provider,支持语言切换 +- 基础语言切换 +- 实现中英文切换功能,通过下拉选择器实时更新页面语言 - _ReactIntl(@kne/current-lib_react-intl)[import * as _ReactIntl from "@kne/react-intl"],antd(antd) ```jsx @@ -85,6 +88,81 @@ render(); ``` +- 远程加载语言 +- 支持API远程动态加载语言包,扩展多语言支持至日语和德语 +- _ReactIntl(@kne/current-lib_react-intl)[import * as _ReactIntl from "@kne/react-intl"],antd(antd),remoteLoader(@kne/remote-loader) + +```jsx +const { createIntlProvider, FormattedMessage } = _ReactIntl; +const { Select, Flex } = antd; +const { useState } = React; +const { createWithRemoteLoader } = remoteLoader; + +const IntlProvider = createIntlProvider({ + defaultLocale: 'zh-CN', + namespace: 'test', + messages: { + 'zh-CN': { + hello: '你好,世界!', + remove: '删除' + }, + 'en-US': { + hello: 'Hello, world!', + remove: 'remove' + } + } +}); + +const BaseExample = createWithRemoteLoader({ + modules: ['components-core:Global@PureGlobal'] +})(({ remoteModules }) => { + const [PureGlobal] = remoteModules; + const [locale, setLocale] = useState('zh-CN'); + return ( + { + console.log('params', data); + const lang = { + 'ja-JP': { + hello: 'こんにちは、世界!' + }, + 'de-DE': { + hello: 'Hallo, Welt!' + } + }; + + return Promise.resolve(lang[data.locale]); + } + } + } + }}> + + + + + + + + ); +}); + +render(); diff --git a/doc/summary.md b/doc/summary.md index d550856..e197dcc 100644 --- a/doc/summary.md +++ b/doc/summary.md @@ -5,3 +5,7 @@ 适用于需要快速实现国际化功能的 React 应用,特别适合中大型项目的多语言支持,包括电商网站、SaaS 平台、企业后台管理系统等场景。支持组件级和全局级的语言配置,可以根据不同模块独立管理翻译内容。 技术亮点在于提供了多种创建方式,createIntlProvider 用于创建完整的国际化上下文,createWithIntlProvider 可以为单个组件注入国际化能力,createIntl 则适用于非组件环境的国际化场景。消息加载器支持单个和批量加载,命名空间机制确保不同模块的翻译内容互不干扰。 + +***远程加载语言包*** + +远程加载语言包功能支持通过 API 动态获取翻译内容,当本地缺少某语言的翻译时自动触发远程请求。提供智能缓存机制,避免重复请求相同的语言包,适用于按需加载、动态扩展语言支持、分包优化等场景。开发者可通过配置全局上下文的 localeMessage 接口,灵活集成后端翻译服务,实现运营人员动态管理翻译内容,无需重新部署应用。 \ No newline at end of file diff --git a/package.json b/package.json index 92c47a4..4174f53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kne/react-intl", - "version": "0.1.10", + "version": "0.1.11-alpha.0", "description": "快捷地创建国际化中需要使用到的组件", "syntax": { "esmodules": true @@ -88,6 +88,7 @@ }, "dependencies": { "@kne/global-context": ">=1", + "@kne/react-fetch": ">=1", "react-intl": "^6.8.9" } } diff --git a/src/createWithFetchLang.js b/src/createWithFetchLang.js new file mode 100644 index 0000000..95415e5 --- /dev/null +++ b/src/createWithFetchLang.js @@ -0,0 +1,53 @@ +import Fetch from '@kne/react-fetch'; +import { useGlobalValue, usePreset } from '@kne/global-context'; +import localeLoader, { messagesLoader, message } from './loader'; +import { IntlProvider } from 'react-intl'; +import React, { forwardRef } from 'react'; + +const argsParse = (...args) => { + if (typeof args[0] === 'object' && typeof args[0].defaultLocale === 'string') { + return Object.assign({}, args[0]); + } + + return { defaultLocale: args[0], defaultMessage: args[1], namespace: args[2] }; +}; + +const createWithFetchLang = (...args) => { + const { defaultLocale, defaultMessage, namespace, messages } = argsParse(...args); + defaultMessage && localeLoader(defaultLocale, defaultMessage, namespace); + messages && messagesLoader(messages, namespace); + return WrappedComponents => + forwardRef(({ locale: propsLocale, ...props }, ref) => { + const { apis } = usePreset(); + const contextLocal = useGlobalValue('locale'); + const locale = propsLocale || contextLocal || defaultLocale || 'zh-CN'; + const currentNamespace = namespace || 'global'; + const messages = message[locale]?.[currentNamespace]; + const defaultLocalMessage = message[defaultLocale || 'zh-CN']?.[currentNamespace]; + if (apis?.localeMessage && !(messages && Object.keys(messages).length > 0) && defaultLocalMessage && Object.keys(defaultLocalMessage).length > 0) { + return ( + { + messagesLoader({ [locale]: data }, currentNamespace); + const messages = message[locale]?.[currentNamespace]; + return ( + + + + ); + }} + /> + ); + } + + return ( + + + + ); + }); +}; + +export default createWithFetchLang; diff --git a/src/index.js b/src/index.js index ab7ced9..dc10768 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ import React, { forwardRef } from 'react'; import localeLoader, { message, messagesLoader } from './loader'; import { IntlProvider, createIntl as createIntlBase, useIntl } from 'react-intl'; import { useGlobalValue } from '@kne/global-context'; +import createWithFetchLang from './createWithFetchLang'; const withIntlProvider = WrappedComponents => forwardRef(({ locale: propsLocale, namespace, ...props }, ref) => { @@ -23,39 +24,17 @@ const argsParse = (...args) => { }; export const createIntlProvider = (...args) => { - const { defaultLocale, defaultMessage, namespace, messages } = argsParse(...args); - defaultMessage && localeLoader(defaultLocale, defaultMessage, namespace); - messages && messagesLoader(messages, namespace); + const withIntlProvider = createWithFetchLang(...args); const InnerComponent = ({ children }) => { const intl = useIntl(); return children(intl); }; - return ({ locale: propsLocale, children }) => { - const contextLocal = useGlobalValue('locale'); - const locale = propsLocale || contextLocal || defaultLocale || 'zh-CN'; - return ( - - {typeof children === 'function' ? {children} : children} - - ); - }; + return withIntlProvider(({ locale: propsLocale, children }) => { + return typeof children === 'function' ? {children} : children; + }); }; -export const createWithIntlProvider = (...args) => { - const { defaultLocale, defaultMessage, namespace, messages } = argsParse(...args); - defaultMessage && localeLoader(defaultLocale, defaultMessage, namespace); - messages && messagesLoader(messages, namespace); - return WrappedComponents => - forwardRef(({ locale: propsLocale, ...props }, ref) => { - const contextLocal = useGlobalValue('locale'); - const locale = propsLocale || contextLocal || defaultLocale || 'zh-CN'; - return ( - - - - ); - }); -}; +export const createWithIntlProvider = createWithFetchLang; export * from 'react-intl';