Skip to content

Commit

Permalink
⭐ new: add sync option
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon committed Mar 8, 2017
1 parent afb6d8f commit 5c46c07
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 4 deletions.
8 changes: 6 additions & 2 deletions decls/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ declare type I18nOptions = {
formatter?: Formatter,
missing?: MissingHandler,
root?: I18n,
fallbackRoot?: boolean
fallbackRoot?: boolean,
sync?: boolean
}

declare interface I18n {
static install: () => void,
static version: string,
get vm() :any,
get locale (): string,
set locale (locale: string): void,
get fallbackLocale (): string,
Expand All @@ -29,7 +31,9 @@ declare interface I18n {
set formatter (formatter: Formatter): void,
t (key: string, ...args: any): string,
tc (key: string, choice?: number, ...args: any): any,
te (key: string, ...args: any): boolean
te (key: string, ...args: any): boolean,
watchLocale (): any,
unwatchLocale (): boolean
}

declare type FormatterOptions = Dictionary<any>
Expand Down
23 changes: 23 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ export default class VueI18n {
_vm: any
_formatter: Formatter
_root: ?I18n
_sync: ?boolean
_fallbackRoot: boolean
_fallbackLocale: string
_missing: ?MissingHandler
_exist: Function
_watcher: any

constructor (options: I18nOptions = {}) {
const locale: string = options.locale || 'en-US'
Expand All @@ -27,6 +29,7 @@ export default class VueI18n {
this._formatter = options.formatter || new BaseFormatter()
this._missing = options.missing
this._root = options.root || null
this._sync = options.sync || false
this._fallbackRoot = options.fallbackRoot || false

this._exist = (message: Object, key: string): boolean => {
Expand All @@ -44,6 +47,26 @@ export default class VueI18n {
Vue.config.silent = silent
}

watchLocale (): any {
if (!this._sync || !this._root) { return null }
const target: any = this._vm
this._watcher = this._root.vm.$watch('locale', (val) => {
target.$set(target, 'locale', val)
}, { immediate: true })
return this._watcher
}

unwatchLocale (): boolean {
if (!this._sync || !this._watcher) { return false }
if (this._watcher) {
this._watcher()
delete this._watcher
}
return true
}

get vm (): any { return this._vm }

get messages (): Messages { return this._vm.$data.messages }
set messages (messages: Messages): void { this._vm.$set(this._vm, 'messages', messages) }

Expand Down
10 changes: 9 additions & 1 deletion src/mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ export default {
options.i18n.root = this.$root.$i18n
}
this.$i18n = new VueI18n(options.i18n)
if (options.i18n.sync) {
this._localeWatcher = this.$i18n.watchLocale()
}
} else {
if (process.env.NODE_ENV !== 'production') {
warn(`Cannot be interpreted 'i18n' options.`)
warn(`Cannot be interpreted 'i18n' option.`)
}
}
} else if (this.$root && this.$root.$i18n && typeName(this.$root.$i18n) === 'VueI18n') {
Expand All @@ -65,6 +68,11 @@ export default {
},

destroyed () {
if (this._localeWatcher) {
this.$i18n.unwatchLocale()
delete this._localeWatcher
}

this.$i18n = null
}
}
23 changes: 22 additions & 1 deletion test/unit/component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,26 @@ describe('component translation', () => {
}
},
child2: {
components: {
'sub-child2': {
i18n: {
sync: true,
messages: {
en: { who: 'sub-child2' },
ja: { who: 'サブの子2' }
}
},
render (h) {
return h('div', {}, [
h('p', { ref: 'who' }, [this.$t('who')])
])
}
}
},
render (h) {
return h('div', {}, [
h('p', { ref: 'who' }, [this.$t('who')])
h('p', { ref: 'who' }, [this.$t('who')]),
h('sub-child2', { ref: 'sub-child2' })
])
}
}
Expand All @@ -70,11 +87,13 @@ describe('component translation', () => {
const child1Fallback = vm.$refs.child1.$refs.fallback
const child2 = vm.$refs.child2.$refs.who
const subChild1 = vm.$refs.child1.$refs['sub-child1'].$refs.who
const subChild2 = vm.$refs.child2.$refs['sub-child2'].$refs.who
assert.equal(root.textContent, 'ルート')
assert.equal(child1.textContent, 'child1')
assert.equal(child1Fallback.textContent, 'フォールバック')
assert.equal(child2.textContent, 'ルート')
assert.equal(subChild1.textContent, 'ルート')
assert.equal(subChild2.textContent, 'サブの子2')

// change locale
i18n.locale = 'en'
Expand All @@ -85,6 +104,8 @@ describe('component translation', () => {
assert.equal(child1Fallback.textContent, 'fallback')
assert.equal(child2.textContent, 'root')
assert.equal(subChild1.textContent, 'root')
assert.equal(subChild2.textContent, 'sub-child2')

vm.$destroy()
}).then(() => {
assert(vm.$i18n === null)
Expand Down

0 comments on commit 5c46c07

Please sign in to comment.