Skip to content

Commit 3fb6d68

Browse files
authored
fix: message update in slot (#63)
* fix: message update in slot closes #60 * fix: remove
1 parent 8075db6 commit 3fb6d68

File tree

11 files changed

+278
-56
lines changed

11 files changed

+278
-56
lines changed

examples/composable/scope/global.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ <h1>Root</h1>
2323
const { createApp } = Vue
2424
const { createI18n, useI18n } = VueI18n
2525

26+
const SlotChild = {
27+
template: `
28+
<p><slot/></p>
29+
`
30+
}
31+
2632
const SubChild = {
2733
template: `
2834
<div class="sub-child">
@@ -44,7 +50,8 @@ <h1>Sub Child</h1>
4450

4551
const Child = {
4652
components: {
47-
SubChild
53+
SubChild,
54+
SlotChild
4855
},
4956
template: `
5057
<div class="child">
@@ -58,6 +65,14 @@ <h1>Child</h1>
5865
</form>
5966
<p>{{ t('message.hi') }}</p>
6067
<SubChild />
68+
t inside of slot
69+
<SlotChild>
70+
{{ t('message.hi') }}
71+
</SlotChild>
72+
i18n-t inside of slot
73+
<SlotChild>
74+
<i18n-t keypath='message.hi'/>
75+
</SlotChild>
6176
</div>
6277
`,
6378
setup() {

examples/legacy/fallback/basic.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
const i18n = createI18n({
1818
legacy: true,
1919
locale: 'ja',
20-
fallbackLocale: 'en',
20+
fallbackLocale: ['en'],
2121
messages: {
2222
en: {
2323
message: {

examples/legacy/fallback/suppress.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
const i18n = createI18n({
1818
legacy: true,
1919
locale: 'ja',
20-
fallbackLocale: 'en',
20+
fallbackLocale: ['en'],
2121
silentFallbackWarn: true, // warning off
2222
messages: {
2323
en: {

examples/legacy/missing/handler.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
const i18n = createI18n({
1818
legacy: true,
1919
locale: 'ja',
20-
fallbackLocale: 'en',
20+
fallbackLocale: ['en'],
2121
missing: (locale, key, instance) => {
2222
// something to do ...
2323
console.warn(`detect '${key}' key missing in '${locale}'`)

examples/legacy/missing/suppress.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
const i18n = createI18n({
1818
legacy: true,
1919
locale: 'ja',
20-
fallbackLocale: 'en',
20+
fallbackLocale: ['en'],
2121
silentTranslationWarn: true, // warning off
2222
messages: {
2323
en: {

examples/legacy/scope/global.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ <h1>Root</h1>
2323
const { createApp } = Vue
2424
const { createI18n } = VueI18n
2525

26+
const SlotChild = {
27+
template: `
28+
<p><slot/></p>
29+
`
30+
}
31+
2632
const SubChild = {
2733
template: `
2834
<div class="sub-child">
@@ -41,7 +47,8 @@ <h1>Sub Child</h1>
4147

4248
const Child = {
4349
components: {
44-
SubChild
50+
SubChild,
51+
SlotChild
4552
},
4653
template: `
4754
<div class="child">
@@ -55,6 +62,14 @@ <h1>Child</h1>
5562
</form>
5663
<p>{{ $t('message.hi') }}</p>
5764
<SubChild />
65+
$t inside of slot
66+
<SlotChild>
67+
{{ $t('message.hi') }}
68+
</SlotChild>
69+
i18n-t inside of slot
70+
<SlotChild>
71+
<i18n-t keypath='message.hi'/>
72+
</SlotChild>
5873
</div>
5974
`
6075
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"ts-jest": "^26.0.0",
6565
"typescript": "^3.8.3",
6666
"typescript-eslint-language-service": "^3.0.0",
67-
"vue": "^3.0.0-beta.14"
67+
"vue": "^3.0.0-beta.15"
6868
},
6969
"engines": {
7070
"node": ">= 10"
@@ -87,7 +87,7 @@
8787
"main": "dist/vue-i18n.cjs.js",
8888
"module": "dist/vue-i18n.esm-bundler.js",
8989
"peerDependencies": {
90-
"vue": "^3.0.0-beta.14"
90+
"vue": "^3.0.0-beta.15"
9191
},
9292
"repository": {
9393
"type": "git",

src/composer.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -467,16 +467,9 @@ export function createComposer(
467467
fallbackFail: (key: string) => T,
468468
successCondition: (val: unknown) => boolean
469469
): ComputedRef<T> {
470-
// NOTE:
471-
// if this composer is global (__root is `undefined`), add dependency trakcing!
472-
// by containing this, we can reactively notify components that reference the global composer.
473-
if (!_isGlobal) {
474-
_locale.value
475-
}
476-
477470
return computed<T>(
478471
(): T => {
479-
const ret = fn(_context)
472+
const ret = fn(getRuntimeContext())
480473
if (isNumber(ret) && ret === NOT_REOSLVED) {
481474
const key = argumentParser()
482475
if (__DEV__ && _fallbackRoot && __root) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`slot reactivity compsable: en 1`] = `"<h1>Root</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>hello!</p><div class=\\"child\\"><h1>Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>hello!</p><div class=\\"sub-child\\"><h1>Sub Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>hello!</p></div> t inside of slot <p>hello!</p> i18n-t inside of slot <p>hello!</p></div>"`;
4+
5+
exports[`slot reactivity compsable: ja 1`] = `"<h1>Root</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>こんにちは!</p><div class=\\"child\\"><h1>Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>こんにちは!</p><div class=\\"sub-child\\"><h1>Sub Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>こんにちは!</p></div> t inside of slot <p>こんにちは!</p> i18n-t inside of slot <p>こんにちは!</p></div>"`;
6+
7+
exports[`slot reactivity legacy: en 1`] = `"<h1>Root</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>hello!</p><div class=\\"child\\"><h1>Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>hello!</p><div class=\\"sub-child\\"><h1>Sub Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>hello!</p></div> $t inside of slot <p>hello!</p> i18n-t inside of slot <p>hello!</p></div>"`;
8+
9+
exports[`slot reactivity legacy: ja 1`] = `"<h1>Root</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>こんにちは!</p><div class=\\"child\\"><h1>Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>こんにちは!</p><div class=\\"sub-child\\"><h1>Sub Child</h1><form><select><option value=\\"en\\">en</option><option value=\\"ja\\">ja</option></select></form><p>こんにちは!</p></div> $t inside of slot <p>こんにちは!</p> i18n-t inside of slot <p>こんにちは!</p></div>"`;

test/i18n.test.ts

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @jest-environment jsdom
33
*/
44

5-
import { defineComponent } from 'vue'
5+
import { defineComponent, nextTick } from 'vue'
66
import { mount } from './helper'
77
import { createI18n, useI18n } from '../src/i18n'
88
import { errorMessages, I18nErrorCodes } from '../src/errors'
@@ -233,3 +233,193 @@ describe('useI18n', () => {
233233
)
234234
})
235235
})
236+
237+
describe('slot reactivity', () => {
238+
let org, spy
239+
beforeEach(() => {
240+
org = console.warn
241+
spy = jest.fn()
242+
console.warn = spy
243+
})
244+
afterEach(() => {
245+
console.warn = org
246+
})
247+
248+
test('legacy', async () => {
249+
const i18n = createI18n({
250+
legacy: true,
251+
locale: 'ja',
252+
fallbackLocale: ['en'],
253+
messages: {
254+
en: {
255+
hello: 'hello!'
256+
},
257+
ja: {
258+
hello: 'こんにちは!'
259+
}
260+
}
261+
})
262+
263+
const SlotChild = {
264+
template: `<p><slot/></p>`
265+
}
266+
267+
const SubChild = {
268+
template: `
269+
<div class="sub-child">
270+
<h1>Sub Child</h1>
271+
<form>
272+
<select v-model="$i18n.locale">
273+
<option value="en">en</option>
274+
<option value="ja">ja</option>
275+
</select>
276+
</form>
277+
<p>{{ $t('hello') }}</p>
278+
</div>
279+
`
280+
}
281+
282+
const Child = {
283+
components: {
284+
SubChild,
285+
SlotChild
286+
},
287+
template: `
288+
<div class="child">
289+
<h1>Child</h1>
290+
<form>
291+
<select v-model="$i18n.locale">
292+
<option value="en">en</option>
293+
<option value="ja">ja</option>
294+
</select>
295+
</form>
296+
<p>{{ $t('hello') }}</p>
297+
<SubChild />
298+
$t inside of slot
299+
<SlotChild>
300+
{{ $t('hello') }}
301+
</SlotChild>
302+
i18n-t inside of slot
303+
<SlotChild>
304+
<i18n-t keypath='hello'/>
305+
</SlotChild>
306+
</div>
307+
`
308+
}
309+
310+
const App = defineComponent({
311+
components: {
312+
Child
313+
},
314+
template: `
315+
<h1>Root</h1>
316+
<form>
317+
<select v-model="$i18n.locale">
318+
<option value="en">en</option>
319+
<option value="ja">ja</option>
320+
</select>
321+
</form>
322+
<p>{{ $t('hello') }}</p>
323+
<Child />
324+
`
325+
})
326+
const { html } = await mount(App, i18n)
327+
expect(html()).toMatchSnapshot('ja')
328+
i18n.global.locale.value = 'en'
329+
await nextTick()
330+
expect(html()).toMatchSnapshot('en')
331+
})
332+
333+
test('compsable', async () => {
334+
const i18n = createI18n({
335+
locale: 'ja',
336+
fallbackLocale: ['en'],
337+
messages: {
338+
en: {
339+
hello: 'hello!'
340+
},
341+
ja: {
342+
hello: 'こんにちは!'
343+
}
344+
}
345+
})
346+
347+
const SlotChild = {
348+
template: `<p><slot/></p>`
349+
}
350+
351+
const SubChild = {
352+
template: `
353+
<div class="sub-child">
354+
<h1>Sub Child</h1>
355+
<form>
356+
<select v-model="locale">
357+
<option value="en">en</option>
358+
<option value="ja">ja</option>
359+
</select>
360+
</form>
361+
<p>{{ t('hello') }}</p>
362+
</div>
363+
`,
364+
setup() {
365+
return useI18n()
366+
}
367+
}
368+
369+
const Child = {
370+
components: {
371+
SubChild,
372+
SlotChild
373+
},
374+
template: `
375+
<div class="child">
376+
<h1>Child</h1>
377+
<form>
378+
<select v-model="locale">
379+
<option value="en">en</option>
380+
<option value="ja">ja</option>
381+
</select>
382+
</form>
383+
<p>{{ t('hello') }}</p>
384+
<SubChild />
385+
t inside of slot
386+
<SlotChild>
387+
{{ t('hello') }}
388+
</SlotChild>
389+
i18n-t inside of slot
390+
<SlotChild>
391+
<i18n-t keypath='hello'/>
392+
</SlotChild>
393+
</div>
394+
`,
395+
setup() {
396+
return useI18n()
397+
}
398+
}
399+
400+
const App = defineComponent({
401+
components: {
402+
Child
403+
},
404+
template: `
405+
<h1>Root</h1>
406+
<form>
407+
<select v-model="locale">
408+
<option value="en">en</option>
409+
<option value="ja">ja</option>
410+
</select>
411+
</form>
412+
<p>{{ t('hello') }}</p>
413+
<Child />
414+
`,
415+
setup() {
416+
return useI18n()
417+
}
418+
})
419+
const { html } = await mount(App, i18n)
420+
expect(html()).toMatchSnapshot('ja')
421+
i18n.global.locale.value = 'en'
422+
await nextTick()
423+
expect(html()).toMatchSnapshot('en')
424+
})
425+
})

0 commit comments

Comments
 (0)