【问题标题】:Capsuled data sharing with Vuex, axios & several component instances与 Vuex、axios 和多个组件实例进行封装数据共享
【发布时间】:2021-02-26 17:19:40
【问题描述】:

我有一个组件QuestionContainer.vue 有几个问题(输入表单)。使用名为 keyUpRoutine(questionkey) 的方法对每个用户给出的答案(用户输入)进行实时验证 (@keyup.prevent="keyUpRoutine(questionkey)")。如果所有答案都有效,我会执行一致性检查:

在 QuestionContainer.vue 中:

keyUpRoutine(questionkey) {

    var value = event.target.value;
    var question = this.questions[questionkey];

    question.validated = this.validate(question, value) ?  true : false;

    this.allConditioncomplied() 
        ? this.$store.dispatch("checkObligationConsistency", { someData })
        : this.questionState = 'default';
        // this.questionState must be changed by Vuex' action (app.js) checkObligationConsistency()
}

app.js 中的操作:

checkObligationConsistency(context, obligation) {
    context.commit("SET_OBLIGATION_STATE", "checking");
    axios
        .post("/DataCheck/checkObligationConsistency", obligation)
        .then(function(response) {

            context.commit("SET_OBLIGATION_STATE", "valid");
            
            if (store.state.modalType == "QuestionPack") {
                context.commit("SET_QUESTION_STATE", "add");
                // In QuestionContainer.vue, this.questionState must be set to 'add'
                // Incorrect approach: store.state.questionState = "add";
            } else {
                context.commit("SET_QUESTION_STATE", "submit");
                // In QuestionContainer.vue, this.questionState must be set to 'submit'                
                // Incorrect approach: store.state.questionState = "submit";
            }

        })
        .catch(function(error) {
            console.log(error);
            context.commit("SET_OBLIGATION_STATE", "invalid");

        });
}

问题的症结:组件QuestionContainer.vue可能存在两次(常规,有时在模态div中),因此使用Vuex状态将不起作用,因为必须在每个组件中隔离状态.

有没有办法返回 QuestionContainer.vue 的 questionState 的新值并将其封装在每个组件中?

【问题讨论】:

    标签: javascript vue.js axios vue-component vuex


    【解决方案1】:

    我遇到了类似的问题,我必须存储同一组件的多个实例的状态。因此,目前您的突变会更新商店中的单个属性。我的方法不是这样做,而是为此状态创建一个对象数组。例如,你的突变应该像这样工作: App.js

    context.commit("SET_OBLIGATION_STATE", {index: 0, value: "valid"});
    

    store/state.js

    // You can instantiate it with all your instances of this component or add them dynamically
    { obligationState: [ { value: "valid" } ] }
    

    store/mutation.js

    SET_OBLIGATION_STATE(state, payload) {
        Vue.set(state.obligationState, payload.index, payload.value)
    },
    

    QuestionContainer.vue

    // You can pass here the index of your component instance and then 'checkObligationConsistency' action will know which instance state to update
    this.$store.dispatch("checkObligationConsistency", { someData, index })
    

    【讨论】:

    • 请注意 state.obligationState[payload.index] = payload.value; 不会被 Vue 的反应性选中。请改用Vue.set(this.obligationState, payload.index, payload.value)
    • @DigitalDrifter 是的,我忘了提这个。谢谢!
    • @DigitalDrifter 实际上在 Vue v3 中我认为它可能在没有 Vue.set() 的情况下工作,因为反应系统是用 Proxy 重写的。你觉得怎么样,到目前为止你有没有尝试过?
    • 谢谢@NikolayYankov!您的方法取得了成功:-)
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 2020-03-25
    • 2012-06-27
    • 2020-03-28
    • 1970-01-01
    • 2020-12-05
    • 2019-05-15
    • 1970-01-01
    相关资源
    最近更新 更多