2018年3月17日 星期六

[Vue] Custom plugin for getting i18n data with vue-i18n (1)


  Vue.js    vue-i18n     Plugins


Introduction


In previous article, we can get the internationalization data from backend.
We will talk about some tips of creating a plugin for global-level getting-i18n-function.

Goals:

1.  Creating plugin for getting i18n data by certain keyword.
2.  Embed the plugin and assign the keyword for it.





Environment


vue.js 2.5.13
vue-i18n 7.4.2
ASP.NET Web API 2



Implement


JS function for reading embedded file’s parameter

function getJsFileParameter(fileId, key) {
    var script_tag = document.getElementById(fileId);

    if (script_tag) {
        var query = script_tag.src.replace(/^[^\?]+\??/, '');
        // Parse the query string into arguments and parameters
        var vars = query.split("&");
        var args = {};
        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split("=");
            args[pair[0]] = decodeURI(pair[1]).replace(/\+/g, ' ');
        }
        return args[key];
    }
    else
        return "";
}

So when we embed some js files like following,

<script src="~/wwwroot/js/build/baseapp.min.js?name=JB" id="my_name_js"></script>
<script src="~/wwwroot/js/build/baseapp.min.js?phone=0933XXXXX" id="my_phone_js"></script>

and we can get the values of the url parameters like this,
console.log(getJsFileParameter('my_name_js', 'name'));
console.log(getJsFileParameter('my_phone_js', 'phone'));

Which will results in,

JB
0933XXXXX



Create plugin for getting-i18n-data

We will create a Vue plugin for
1.  Initializing vue-i18n
2.  Getting i18n data from backend


JS



Vue.use(VueI18n);

// Create VueI18n instance with options
const i18n = new VueI18n({
    locale: ''// set locale
    fallbackLocale: 'zhTW',

});

var I18nPlugin = {
    install: function (Vue, options) {

        // Vue.mixin() for injecting functionality into all components.
        Vue.mixin({
            created() {
                if (this.isLoadI18n) {
                    let id = getJsFileParameter('i18n', 'id');
                    if (id) {
                        let getEnUS = this.getI18n(id, 'en-US');
                        let getZhTW = this.getI18n(id, 'zh-TW');
                        let getZhCN = this.getI18n(id, 'zh-CN');

                        let i18nPromise = axios.all([getEnUS, getZhTW, getZhCN])
                            .then(axios.spread(function (response1, response2, response3) {
                                i18n.setLocaleMessage('enUS', response1.data);
                                i18n.setLocaleMessage('zhTW', response2.data);
                                i18n.setLocaleMessage('zhCN', response3.data);
                                i18n.locale = Vue.prototype.$locale;
                            }));
                    }
                }
            },
            mounted() { }
        });

        Vue.prototype.getI18n = function (idlang) {
            let uri = Vue.prototype.$I18N.concat(id"?lang="lang);
            return axios.get(uri);
        }
    }


};

Notice that I want to request the i18n data once when the major component is created. However the codes in Vue.mixin() will be triggered every time a component is created, so we set an extra constraint like this:

Vue.mixin({
            created() {
                if (this.isLoadI18n) {
                    //Do something...
                }
            },
});


Use the plugin

To enable vue-i18n and our custom plugin, here are the steps,

Embed i18n.plugin.js with script id and url parameter

<script src="~/wwwroot/js/app/plugin/i18n.plugin.js?id=Organization" id="i18n"></script>


Use the plugin in component and set local data: isLoadI18n

Vue.use(I18nPlugin);

var app = new Vue({
    el: '#app',
    i18n: i18n,
    data: {
        isLoadI18n: true,
    }
})




Reference




沒有留言:

張貼留言