简体   繁体   English

带有Vuex.js的Vue.js组件(而不是vue-i18n.js)

[英]Vue.js component with Vuex.js (instead of vue-i18n.js)

I've been trying to reproduce the button behavior that I've here , but with a different implementation. 我一直在尝试重现我在这里的按钮行为,但是使用了不同的实现。 Basically, I'm trying to use Vuex instead of vue-i18n.js for internationalization purposes. 基本上,我正在尝试使用Vuex代替vue-i18n.js进行国际化。

I now have the following code block, the purpose of which is to create language states and perform a XMLHttpRequest (for the .json files storing the various translations): 我现在有以下代码块,其目的是创建语言状态并执行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;
        }
    }

});

On my component constructor (created and initialized in the root Vue instance), I've the following: 在我的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
            }
        }
    }

On my root Vue instance's data object , I've added the following: 在我的root Vue instance's data object ,添加了以下内容:

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

And finally, on my html : 最后,在我的html

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

I cannot figure out what I'm doing wrong here. 我无法弄清楚我在做什么错。


UPDATE 更新

Here's a JsFiddle (I've exchanged the XMLHttpRequest request for json arrays). 这是一个JsFiddle(我已经将XMLHttpRequest请求交换为json数组)。 Also, this is a working example, but the language selector buttons do not hide when the respective language is selected, which is the opposite of what I want. 另外, 是一个有效的示例,但是当选择了相应的语言时,语言选择器按钮不会隐藏,这与我想要的相反。 Meaning that, I'm attempting to hide each individual language selector button when the user clicks it and selects the respective language (while showing the other language selector buttons). 就是说,我试图在用户单击每个语言选择器按钮并选择相应的语言时隐藏它们(同时显示其他语言选择器按钮)。

The solution involves saving an active state in the store , in addition to the lang state: 该解决方案除了将lang状态外,还将active状态保存在store中:

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

Adding an ACTIVE mutation : 添加一个ACTIVE mutation

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

On the computed properties block, one also needs to add getter functions for the active state and return the langcode that is currently active : 所计算的属性框,一个也需要增加吸气剂功能的active状态,并返回langcode是当前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'
        }
    }
})

Then, it is just a question of conditionally displaying each of the buttons on the component template by adding v-show="!enIsActive" , v-show="!frIsActive" , etc.: 然后,这只是通过添加v-show="!enIsActive"v-show="!frIsActive"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>',

Finally, on the activate method, adding a new line to change the active state when the user clicks a button: 最后,在activate方法上,添加新行以更改用户单击按钮时的active状态:

methods: {
    activate: function(x) {
      storelang.dispatch('LANG', x)
      storelang.dispatch('ACTIVE', x)
    }
  }, 

The full working code here . 完整的工作代码在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM