Skip to content

Commit edaf498

Browse files
committed
fix: cannot resolve flatjson messages
resolve #1595
1 parent bd7ec22 commit edaf498

File tree

2 files changed

+137
-2
lines changed

2 files changed

+137
-2
lines changed

packages/vue-i18n-core/src/composer.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
isPlainObject,
1212
isObject,
1313
assign,
14-
inBrowser
14+
inBrowser,
15+
hasOwn
1516
} from '@intlify/shared'
1617
import {
1718
isTranslateFallbackWarn,
@@ -53,7 +54,8 @@ import {
5354
deepCopy,
5455
getLocaleMessages,
5556
getComponentOptions,
56-
createTextNode
57+
createTextNode,
58+
handleFlatJson
5759
} from './utils'
5860
import { VERSION } from './misc'
5961

@@ -1848,6 +1850,7 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any {
18481850
NumberFormatsType
18491851
>
18501852
const _isGlobal = __root === undefined
1853+
const flatJson = options.flatJson
18511854

18521855
let _inheritLocale = isBoolean(options.inheritLocale)
18531856
? options.inheritLocale
@@ -2375,6 +2378,15 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any {
23752378

23762379
// setLocaleMessage
23772380
function setLocaleMessage(locale: Locale, message: LocaleMessage<Message>) {
2381+
if (flatJson) {
2382+
const _message = { [locale]: message }
2383+
for (const key in _message) {
2384+
if (hasOwn(_message, key)) {
2385+
handleFlatJson(_message[key])
2386+
}
2387+
}
2388+
message = _message[locale]
2389+
}
23782390
_messages.value[locale] = message
23792391
if (__BRIDGE__) {
23802392
__legacy && __legacy.setLocaleMessage(locale, message)
@@ -2391,6 +2403,13 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any {
23912403
if (__BRIDGE__) {
23922404
__legacy && __legacy.mergeLocaleMessage(locale, message)
23932405
}
2406+
const _message = { [locale]: message }
2407+
for (const key in _message) {
2408+
if (hasOwn(_message, key)) {
2409+
handleFlatJson(_message[key])
2410+
}
2411+
}
2412+
message = _message[locale]
23942413
deepCopy(message, _messages.value[locale])
23952414
_context.messages = _messages.value as typeof _context.messages
23962415
}

packages/vue-i18n-core/test/issues.test.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,3 +1049,119 @@ test('issue #1547', async () => {
10491049

10501050
expect(wrapper.html()).toEqual('<div>Deep Linked message</div>')
10511051
})
1052+
1053+
test('issue #1595', async () => {
1054+
const i18n = createI18n({
1055+
legacy: false,
1056+
locale: 'en',
1057+
flatJson: true,
1058+
messages: {
1059+
en: {
1060+
simple: 'Simple',
1061+
'deep.key': 'Deep',
1062+
content: '@:simple @:deep.key'
1063+
}
1064+
}
1065+
})
1066+
1067+
const ja = {
1068+
simple: 'シンプル',
1069+
'deep.key': 'ディープ',
1070+
content: '@:simple @:deep.key'
1071+
}
1072+
i18n.global.setLocaleMessage('ja', ja)
1073+
1074+
const App = defineComponent({
1075+
setup() {
1076+
const { t, locale } = useI18n()
1077+
return { t, locale }
1078+
},
1079+
template: `<form>
1080+
<select v-model="locale">
1081+
<option value="en">en</option>
1082+
<option value="ja">ja</option>
1083+
</select>
1084+
</form>
1085+
{{ t('content') }}
1086+
`
1087+
})
1088+
1089+
expect(i18n.global.getLocaleMessage('ja')).toEqual({
1090+
simple: 'シンプル',
1091+
deep: {
1092+
key: 'ディープ'
1093+
},
1094+
content: '@:simple @:deep.key'
1095+
})
1096+
1097+
const wrapper = await mount(App, i18n)
1098+
expect(wrapper.html()).toEqual(
1099+
'<form><select><option value="en">en</option><option value="ja">ja</option></select></form> Simple Deep'
1100+
)
1101+
// @ts-ignore
1102+
i18n.global.locale.value = 'ja'
1103+
await nextTick()
1104+
1105+
expect(wrapper.html()).toEqual(
1106+
'<form><select><option value="en">en</option><option value="ja">ja</option></select></form> シンプル ディープ'
1107+
)
1108+
})
1109+
1110+
test('issue #1595 merge case', async () => {
1111+
const i18n = createI18n({
1112+
legacy: false,
1113+
locale: 'en',
1114+
flatJson: true,
1115+
messages: {
1116+
en: {
1117+
simple: 'Simple',
1118+
'deep.key': 'Deep',
1119+
content: '@:simple @:deep.key'
1120+
},
1121+
ja: {
1122+
simple: 'シンプル',
1123+
content: '@:simple @:deep.key'
1124+
}
1125+
}
1126+
})
1127+
1128+
const ja = {
1129+
'deep.key': 'ディープ'
1130+
}
1131+
i18n.global.mergeLocaleMessage('ja', ja)
1132+
1133+
const App = defineComponent({
1134+
setup() {
1135+
const { t, locale } = useI18n()
1136+
return { t, locale }
1137+
},
1138+
template: `<form>
1139+
<select v-model="locale">
1140+
<option value="en">en</option>
1141+
<option value="ja">ja</option>
1142+
</select>
1143+
</form>
1144+
{{ $t('content') }}
1145+
`
1146+
})
1147+
1148+
expect(i18n.global.getLocaleMessage('ja')).toEqual({
1149+
simple: 'シンプル',
1150+
deep: {
1151+
key: 'ディープ'
1152+
},
1153+
content: '@:simple @:deep.key'
1154+
})
1155+
1156+
const wrapper = await mount(App, i18n)
1157+
expect(wrapper.html()).toEqual(
1158+
'<form><select><option value="en">en</option><option value="ja">ja</option></select></form> Simple Deep'
1159+
)
1160+
// @ts-ignore
1161+
i18n.global.locale.value = 'ja'
1162+
await nextTick()
1163+
1164+
expect(wrapper.html()).toEqual(
1165+
'<form><select><option value="en">en</option><option value="ja">ja</option></select></form> シンプル ディープ'
1166+
)
1167+
})

0 commit comments

Comments
 (0)