Vue 自定义插件内使用 vue-i18n 实现国际化
为了将一些业务提取出来,减少项目复杂程度,因此使用自定义插件的方式来实现。
自定义插件
<!-- plugin.vue -->
<template>
<div>
{{ $t('plugin') }}
</div>
</template>
<!-- index.js -->
import Vue from 'vue'
import Plugin from './plugin.vue'
const PluginConstructor = Vue.extend(Plugin)
const plugin = function () {
if (Vue.prototype.$isServer) return
const instance = new PluginConstructor()
instance.$mount()
document.body.appendChild(instance.$el)
return instance
}
const install = (Vue) => {
Vue.prototype.$plugin = plugin
}
export default {
install
}
<!-- main.js -->
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import Plugin from './index.js'
const i18n = new VueI18n({
locale: 'en',
messages: {}
})
Vue.use(Plugin)
new Vue({
i18n,
render: h => h(App)
}).$mount('#root')
但是在其他地方调用 this.$plugin()
时报错:
Vue-i18n "TypeError: Cannot read property '_t' of undefined"
在翻阅了官方的文档之后也没有关于这个问题的解答,查看源码之后发现出现问题的代码在:
if (!Vue.prototype.hasOwnProperty('$i18n')) {
// $FlowFixMe
Object.defineProperty(Vue.prototype, '$i18n', {
get: function get () { return this._i18n }
});
}
var i18n = this.$i18n;
return i18n._t.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this ].concat( values ))
也就是 Vue.prototype.$i18n
未定义,但是直接重定义 $i18n
不可行,只能重定义 Vue.prototype._i18n
。
解决方案
<!-- index.js -->
import Vue from 'vue'
import Plugin from './plugin.vue'
let _i18n = null
export function RewriteLocale (i18n) {
_i18n = i18n
}
const PluginConstructor = Vue.extend(Plugin)
const plugin = function () {
if (Vue.prototype.$isServer) return
const instance = new PluginConstructor()
instance.$mount()
document.body.appendChild(instance.$el)
return instance
}
const install = (Vue) => {
Vue.prototype._i18n = _i18n
Vue.prototype.$plugin = plugin
}
export default {
install
}
<!-- main.js -->
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import Plugin, { RewriteLocale } from './index.js'
const i18n = new VueI18n({
locale: 'en',
messages: {}
})
RewriteLocale(i18n)
Vue.use(Plugin)
new Vue({
i18n,
render: h => h(App)
}).$mount('#root')
评论(1)
博主是个大神,膜拜...