Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ See the below examples:
- [Example with using Composable API](https://github.com/intlify/vue-i18n-next/blob/master/examples/composable/components/datetime-format.html)
- [Example with using Legacy API](https://github.com/intlify/vue-i18n-next/blob/master/examples/legacy/components/datetime-format.html)


## :lollipop: Examples

See the [`examples`](https://github.com/intlify/vue-i18n-next/tree/master/examples) directory.
Expand All @@ -79,7 +78,9 @@ The examples are offered that use the following two API styles:

#### APIs
- The return value of `$t` and `t` methods is **string** only. object and array values ​​are no longer returned.
- As an alternative way, you can use `$tm` / `tm`
- The return value of `$tc` and `tc` methods is **string** only. object and array values ​​are no longer returned.
- As an alternative way, you can use `$tm` / `tm`
- `VueI18n` class cannot used with `new`. It can only be used via the `$i18n` property of Vue instance.
- In vue-i18n-next, by replacing `new VueI18n` with `createI18n`, you can use existing `VueI18n` options as they are.
- See the `examples/legacy` directory.
Expand Down Expand Up @@ -191,6 +192,7 @@ yarn add vue-i18n@next
- [x] setPostTranslationHandler
- [x] getMissingHandler
- [x] setMissingHandler
- [x] tm
- Legacy API: compatible supporting
- VueI18n
- [x] locale
Expand Down Expand Up @@ -225,13 +227,15 @@ yarn add vue-i18n@next
- [x] setNumberFormat
- [x] mergeNumberFormat
- [x] getChoiceIndex
- [x] tm
- Inejctted in Vue Prototype API
- [x] $i18n
- [x] $t
- [x] $tc
- [x] $te
- [x] $d
- [x] $n
- [x] $tm
- Component options
- [x] messages
- [x] pluralRule
Expand Down
17 changes: 16 additions & 1 deletion src/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
VNodeArrayChildren
} from 'vue'
import { WritableComputedRef, ComputedRef } from '@vue/reactivity'
import { Path, parse as parsePath } from './path'
import { Path, parse as parsePath, resolveValue } from './path'
import {
DateTimeFormats as DateTimeFormatsType,
NumberFormats as NumberFormatsType,
Expand All @@ -34,6 +34,7 @@ import {
} from './message/runtime'
import {
Locale,
LocaleMessageValue,
LocaleMessages,
createRuntimeContext,
RuntimeContext,
Expand Down Expand Up @@ -195,6 +196,7 @@ export interface Composer<
n(value: number, key: string, locale: Locale): string
n(value: number, options: NumberOptions): string
n(...args: unknown[]): string // for internal
tm(key: Path): LocaleMessageValue<Message> | {}
getLocaleMessage(locale: Locale): LocaleMessageDictionary<Message>
setLocaleMessage(
locale: Locale,
Expand Down Expand Up @@ -696,6 +698,18 @@ export function createComposer<
)
}

// tm
function tm(key: Path): LocaleMessageValue<Message> | {} {
const messages = _messages.value[_locale.value] || {}
const target = resolveValue(messages, key)
// prettier-ignore
return target != null
? target as LocaleMessageValue<Message>
: __root
? __root.tm(key) as LocaleMessageValue<Message> || {}
: {}
}

// getLocaleMessage
function getLocaleMessage(locale: Locale): LocaleMessageDictionary<Message> {
return (_messages.value[locale] || {}) as LocaleMessageDictionary<Message>
Expand Down Expand Up @@ -869,6 +883,7 @@ export function createComposer<
t,
d,
n,
tm,
getLocaleMessage,
setLocaleMessage,
mergeLocaleMessage,
Expand Down
9 changes: 8 additions & 1 deletion src/legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
LocaleMessages,
LocaleMessageDictionary,
PostTranslationHandler,
FallbackLocale
FallbackLocale,
LocaleMessageValue
} from './core/context'
import { TranslateOptions } from './core/translate'
import {
Expand Down Expand Up @@ -139,6 +140,7 @@ export interface VueI18n<
tc(key: Path, choice: number, named: Record<string, unknown>): TranslateResult
tc(...args: unknown[]): TranslateResult // for $tc
te(key: Path, locale?: Locale): boolean
tm(key: Path): LocaleMessageValue<VueMessageType> | {}
getLocaleMessage(locale: Locale): LocaleMessageDictionary<VueMessageType>
setLocaleMessage(
locale: Locale,
Expand Down Expand Up @@ -510,6 +512,11 @@ export function createVueI18n<
return resolveValue(message, key) !== null
},

// tm
tm(key: Path): LocaleMessageValue<VueMessageType> | {} {
return composer.tm(key)
},

// getLocaleMessage
getLocaleMessage(locale: Locale): LocaleMessageDictionary<VueMessageType> {
return composer.getLocaleMessage(locale)
Expand Down
26 changes: 24 additions & 2 deletions src/mixin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { ComponentOptions, getCurrentInstance } from 'vue'
import { Path } from './path'
import { Locale } from './core/context'
import { Composer, ComposerInternalOptions, CustomBlocks } from './composer'
import { Locale, LocaleMessageValue } from './core/context'
import {
Composer,
ComposerInternalOptions,
CustomBlocks,
VueMessageType
} from './composer'
import {
VueI18n,
VueI18nInternal,
Expand Down Expand Up @@ -134,6 +139,20 @@ declare module '@vue/runtime-core' {
* This property is supported for legacy API only
*/
$n?: (...args: unknown[]) => NumberFormatResult
/**
* translation messages method
*
* @param key - required, target keypath
* @returns locale messages
*
* @remarks
* Get the locale message of `key`.
* Get in preferentially component locale messages than global locale messages.
* If the target locale messages is not found locally, get it from the global, otherwise returns an empty object.
*
* This property is supported for legacy API only
*/
$tm?: (key: Path) => LocaleMessageValue<VueMessageType> | {}
}
}

Expand Down Expand Up @@ -206,6 +225,8 @@ export function defineMixin<Messages, DateTimeFormats, NumberFormats>(
this.$i18n.d(...args)
this.$n = (...args: unknown[]): NumberFormatResult =>
this.$i18n.n(...args)
this.$tm = (key: Path): LocaleMessageValue<VueMessageType> | {} =>
this.$i18n.tm(key)
},

mounted(): void {
Expand All @@ -226,6 +247,7 @@ export function defineMixin<Messages, DateTimeFormats, NumberFormats>(
delete this.$te
delete this.$d
delete this.$n
delete this.$tm

i18n.__deleteInstance(instance)
delete this.$i18n
Expand Down
37 changes: 36 additions & 1 deletion test/composer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
VueMessageType
} from '../src/composer'
import { generateFormatCacheKey } from '../src/utils'
import { watch, nextTick, Text, createVNode } from 'vue'
import { watch, watchEffect, nextTick, Text, createVNode } from 'vue'

describe('locale', () => {
test('default value', () => {
Expand Down Expand Up @@ -670,6 +670,41 @@ describe('n', () => {
})
})

test('tm', async () => {
const composer = createComposer({
locale: 'ja',
messages: {
en: {},
ja: {
foo: {
bar: {
buz: 'hello'
},
codes: {
errors: ['error1', 'error2']
}
}
}
}
})

let messages1 = composer.tm('foo.bar')
let messages2 = composer.tm('foo.codes')
expect(messages1).toEqual({ buz: 'hello' })
expect(messages2).toEqual({ errors: ['error1', 'error2'] })

watchEffect(() => {
messages1 = composer.tm('foo.bar')
messages2 = composer.tm('foo.codes')
})

composer.locale.value = 'en'
await nextTick()

expect(messages1).toEqual({})
expect(messages2).toEqual({})
})

describe('getLocaleMessage / setLocaleMessage / mergeLocaleMessage', () => {
test('basic', () => {
const {
Expand Down
36 changes: 36 additions & 0 deletions test/legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { warn } from '../src/utils'
import { createVueI18n } from '../src/legacy'
import { errorMessages, I18nErrorCodes } from '../src/errors'
import { getWarnMessage, I18nWarnCodes } from '../src/warnings'
import { watchEffect, nextTick } from 'vue'

test('locale', () => {
const i18n = createVueI18n()
Expand Down Expand Up @@ -234,6 +235,41 @@ test('te', () => {
expect(i18n.te('message.hallo', 'ja')).toEqual(false)
})

test('tm', async () => {
const i18n = createVueI18n({
locale: 'ja',
messages: {
en: {},
ja: {
foo: {
bar: {
buz: 'hello'
},
codes: {
errors: ['error1', 'error2']
}
}
}
}
})

let messages1 = i18n.tm('foo.bar')
let messages2 = i18n.tm('foo.codes')
expect(messages1).toEqual({ buz: 'hello' })
expect(messages2).toEqual({ errors: ['error1', 'error2'] })

watchEffect(() => {
messages1 = i18n.tm('foo.bar')
messages2 = i18n.tm('foo.codes')
})

i18n.locale = 'en'
await nextTick()

expect(messages1).toEqual({})
expect(messages2).toEqual({})
})

test('getLocaleMessage / setLocaleMessage / mergeLocaleMessage', () => {
const i18n = createVueI18n({
messages: {
Expand Down