跟着官网来看着并不难,放项目里,这出错那不行的… 慢慢看文档一边整理一边尝试,最终得到了我想要的效果。暂时记下来写成博客,可能不是最好的,但目前先把问题解决了来后面再谈细节和优化的事儿吧
折腾了一上午,犯了很多错… 最终捣鼓出来,算是完成了需求。这里说下自己的理解。Vue里的国际化,其实只是把 所谓的静态内容,标题,文字段落,提示说明等等用vue的响应式data来存储,再根据我们的配置,动态改变这些data,从而实现无刷新语言切换,这和vue自身的响应式数据是一个道理。
渲染原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| VueI18n.prototype._t = function _t (key, _locale, messages, host) { var values = [], len = arguments.length - 4; while ( len-- > 0 ) values[ len ] = arguments[ len + 4 ];
if (!key) { return '' }
var parsedArgs = parseArgs.apply(void 0, values); var locale = parsedArgs.locale || _locale; var ret = this._translate( messages, locale, this.fallbackLocale, key, host, 'string', parsedArgs.params ); if (this._isFallbackRoot(ret)) { if ("development" !== 'production' && !this._silentTranslationWarn) { warn(("Fall back to translate the keypath '" + key + "' with root locale.")); } if (!this._root) { throw Error('unexpected error') } return (ref = this._root).t.apply(ref, [ key ].concat( values )) } else { return this._warnDefault(locale, key, ret, host) } var ref; };
|
1 2 3 4 5 6 7
| Vue.prototype.$t = function (key) { var values = [], len = arguments.length - 1; while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
var i18n = this.$i18n; return i18n._t.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this ].concat( values )) };
|
这是目前用到的一个重要函数,从源码里复制出来。这里Vue原型里添加了一个$t方法,它可传入一个key参数,最后连同信息一起返回。
我们使用的$t即将想要的key 拿到写好的 locale目录下的data中查询,返回对应value这样一个过程,理解了这个思路后后面的就要好办多了。
项目运用
首先安装依赖 npm install vue-i18n -D
先贴一下我的配置,然后慢慢说:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| import Vue from 'vue'; import VueI18n from 'vue-i18n'; import App from './index';
import store from '../../store/index'; import router from '../../router/edrPage/index';
import iView from 'iview'; import en from 'locale/local/en_US'; import zh from 'locale/local/zh_CN'; import zhLocale from 'locale/iviewLocale/zh-CN'; import enLocale from 'locale/iviewLocale/en-US'; import 'iview/dist/styles/iview.css'; Vue.config.productionTip = false; Vue.config.lang = 'en'; Vue.use(VueI18n);
const messages = { en: Object.assign({}, en, enLocale), zh: Object.assign({}, zh, zhLocale) }
const i18n = new VueI18n({ locale: Vue.config.lang, fallbackLocale: 'en', messages })
Vue.use(iView, { i18n(path, options) { let value = i18n.t(path, options); if (value !== null && value !== undefined) return value;
return ''; } });
new Vue({ el: '#app', i18n, router, store, template: '<App/>', components: { App } });
|
我用的iView 2.2版本i18n版本只支持到5.0+明显不成,各种问了之后看到了一个解决方案挺不错,就是上面这个。思路很简单,就是本地创建自己的语言包,然后与iView提供的包合并,其他流程走i18n自己的流程即可
在单文件组件的模版中: (用来测试的随便写了)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <template> <div id="login" class="bg"> <button @click="switchLang">切换语言</button> <h1>{{$t('edr.footer.copyright')}}</h1> </div> </template>
<script> export default { name: 'page-login', data() { return { locale: 'en', } }, mounted() { this.locale = this.$i18n.locale = localStorage.getItem('language') }, methods: { switchLang() { if (this.locale === 'en') { this.locale = this.$i18n.locale = 'zh' localStorage.setItem('language', 'zh') } else { this.locale = this.$i18n.locale = 'en' localStorage.setItem('language', 'en') } } } } </script>
|
现在,点击切换按钮,语言就可实时更改了~
好了,其他的同理,在locale目录下,把我们需要切换的中英文数据管理好即可~ 如果内容多拆开来管理更好
但感觉很麻烦的是,以后写静态数据都不能直接写在模版里了… 也算是长姿势了
至于后端返回的数据…… 暂时不知道,让后端自己先折腾吧
还有一个问题… 整个template里, 全是$t()这样的… 也不知道写了什么,占位符谁是谁… 于是,之前写好的最好还是来一层注释,或者利用良好的class命名来避免开发时的尴尬… 不然拿到同事手中只有两眼懵比了…