使用Vuex.js的Vue.js组件(而不是vue-i18n.js)

时间:2016-03-23 10:56:32

标签: javascript internationalization vue.js

我一直在尝试重现我here的按钮行为,但是使用了不同的实现。基本上,我正在尝试使用Vuex代替vue-i18n.js进行国际化。

我现在有以下代码块,其目的是创建语言状态并执行XMLHttpRequest(对于存储各种翻译的.json文件):

Vue.use(Vuex);
var storelang = new Vuex.Store({
    state: {
        lang: {}
    },
    mutations: {
        LANG: function (state, ln) {
            function loadJSON(callback) {
                var xobj = new XMLHttpRequest();
                xobj.overrideMimeType("application/json");
                xobj.open('GET', '../resources/i18n/' + ln + '.json', true);
                xobj.onreadystatechange = function () {
                if (xobj.readyState == 4 && xobj.status == "200") {
                        callback(xobj.responseText);
                    }
                };
                xobj.send(null);
            }

            loadJSON(function (languageJSON) {
                state.lang = JSON.parse(languageJSON);
            })
        },
        strict: true
    }
});

var mix = Vue.mixin({
    computed: {
        lang: function () {
        return storelang.state.lang;
        }
    }

});

在我的component constructor(在根Vue实例中创建并初始化)中,我有以下内容:

components: {
        lang: {
            template: '<button type="button" class="btn btn-info" @click.prevent=activate(lang.code) @click="setActiveLang" v-show="!isActive">{{ lang.code }}</button>',
            props: [
                'active',
                'lang'
            ],
            computed: {
                isActive: function() {
                    return this.lang.code == this.active.code
                }
            },
            methods: {
                activate: function(code) {
                    storelang.dispatch('LANG', code);
                },
                setActiveLang: function() {
                    this.active = this.lang;
                }
            },
            ready: function() {
                storelang.dispatch('LANG', 'en'); //default language
            }
        }
    }

root Vue instance's data object上,我添加了以下内容:

langs: [{
    code: "en"
}, {
    code: "fr"
}, {
    code: "pt"
}],
active: {
    "code": "pt"
}

最后,在我的html

<div v-for="lang in langs">
    <p>
        <lang :lang="lang" :active.sync="active"></lang>
    </p>
</div>

我无法弄清楚我在这里做错了什么。

更新

Here's一个JsFiddle(我已经为json数组交换了XMLHttpRequest请求)。此外,this是一个工作示例,但语言选择器按钮在选择相应语言时不会隐藏,这与我想要的相反。这意味着,我试图在用户单击它时隐藏每个单独的语言选择按钮并选择相应的语言(同时显示其他语言选择器按钮)。

1 个答案:

答案 0 :(得分:0)

除了active州之外,解决方案还需要在store中保存lang州:

new Vuex.Store({
    state: {
        active: {},
        lang: {}

添加ACTIVE mutation

ACTIVE: function(state, ln) {
        var langcode = 'en'
    //portuguese
    if (ln === 'pt') {
        langcode = 'pt'
    }
    //french
    if (ln === 'fr') {
        langcode = 'fr'
    }
  state.active = langcode
}

在计算的属性块上,还需要为active状态添加getter函数并返回当前langcode的{​​{1}}:

active

然后,只是通过添加Vue.mixin({ computed: { lang: function() { return storelang.state.lang }, enIsActive: function() { return storelang.state.active == 'en' }, frIsActive: function() { return storelang.state.active == 'fr' }, ptIsActive: function() { return storelang.state.active == 'pt' } } }) v-show="!enIsActive"等来有条件地显示组件模板上的每个按钮的问题:

v-show="!frIsActive"

最后,在var langBtn = Vue.extend({ template: '<button type="button" class="btn btn-info" @click.prevent=activate("en") v-show="!enIsActive">en</button><button type="button" class="btn btn-info" @click.prevent=activate("pt") v-show="!ptIsActive">pt</button><button type="button" class="btn btn-info" @click.prevent=activate("fr") v-show="!frIsActive">fr</button>', 方法上,添加新行以在用户点击按钮时更改activate状态:

active

完整的工作代码here