mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-15 01:41:20 +08:00
c8d65bf43d
- Add a component for providing configs - Add `use-locale` hooks into hooks for composable usage - Add `use-locale` for `config-provider` to allow user to provide locale config via `react-like` API - Add test cases against these new features
84 lines
2.0 KiB
TypeScript
84 lines
2.0 KiB
TypeScript
import { getCurrentInstance, provide, reactive, watch } from 'vue'
|
|
import English from '@element-plus/locale/lang/en'
|
|
|
|
import type { InjectionKey, PropType } from 'vue'
|
|
import type { Language } from '@element-plus/locale'
|
|
|
|
export const useLocaleProps = {
|
|
locale: {
|
|
type: Object as PropType<Language>,
|
|
},
|
|
i18n: {
|
|
type: Function as PropType<Translator>,
|
|
},
|
|
}
|
|
|
|
type Translator = (...args: any[]) => string
|
|
|
|
export type LocaleContext = {
|
|
locale: Language
|
|
lang: string
|
|
t: Translator
|
|
}
|
|
|
|
export const LocaleInjectionKey = 'ElLocaleInjection' as unknown as InjectionKey<LocaleContext>
|
|
|
|
export const useLocale = () => {
|
|
const vm = getCurrentInstance()
|
|
const props = vm.props as {
|
|
locale: Language
|
|
i18n: Translator
|
|
}
|
|
const localeContext = reactive({
|
|
...props,
|
|
lang: props.locale.name,
|
|
t: translatorGenerator(props.locale, props.i18n),
|
|
})
|
|
|
|
provide(LocaleInjectionKey, localeContext)
|
|
|
|
watch(() => props, ({ locale, i18n }) => {
|
|
// dayjs.locale(locale.name)
|
|
localeContext.locale = locale
|
|
localeContext.lang = locale.name
|
|
localeContext.t = translatorGenerator(locale, i18n)
|
|
}, { deep: true })
|
|
}
|
|
|
|
|
|
function template(str: string, option) {
|
|
if (!str || !option) return str
|
|
|
|
return str.replace(/\{(\w+)\}/g, (_, key) => {
|
|
return option[key]
|
|
})
|
|
}
|
|
|
|
function translatorGenerator(
|
|
locale: Language,
|
|
externalTranslator?: Translator,
|
|
): Translator {
|
|
return (...args) => {
|
|
const defaultTranslator = (...args: any[]) => {
|
|
const [path, option] = args
|
|
let value
|
|
const array = path.split('.')
|
|
let current = locale
|
|
for (let i = 0, j = array.length; i < j; i++) {
|
|
const property = array[i]
|
|
value = current[property]
|
|
if (i === j - 1) return template(value, option)
|
|
if (!value) return ''
|
|
current = value
|
|
}
|
|
}
|
|
|
|
if (externalTranslator) {
|
|
return externalTranslator(...args) || defaultTranslator(...args)
|
|
}
|
|
return defaultTranslator(...args)
|
|
}
|
|
}
|
|
|
|
export const defaultTranslator = translatorGenerator(English)
|