5

我正在使用mapGettersVueX 的帮助程序,但我仅在页面的第一次加载时遇到了一些问题,它不是反应式的......让我告诉你:

我的 html 模板触发了更改:

<input type="number" value="this.inputValue" @change="this.$store.dispatch('setInputValue', $event.target.value)">

我的商店收到价值

{
    state: {
        appValues: {
            inputValue: null
        },
    },
    getters: {
        getInputValue: (state) => {
            return state.appValues.inputValue;
        },
    },
    mutations: {
        setInputValue(state, value) {
            state.appValues.inputValue = value;
        },
    },
    actions: {
        setInputValue(context, payload) {
            return new Promise((resolve, reject) => {
                context.commit('setInputValue', payload);
                resolve();
            });
        },
    }
}

然后我的组件监听商店:

import {mapGetters} from 'vuex';

computed: {
    ...mapGetters({
        inputValue: 'getInputValue',
    }),
}
watch: {
    inputValue: {
        deep: true,
        immediate: true,
        handler(nVal, oVal) {
            console.log("inputValue", nVal, oVal);
        }
    },
}

所以现在,当我第一次加载页面时,我得到了这个 console.log "inputValue" null undefined,这是完全正常的,因为我的商店里什么都没有,它给了我默认值null

但现在是奇怪的部分。我开始更改输入值,但我的控制台中没有任何内容。什么都没有动...

然后我重新加载页面并在加载时得到这个console.log "inputValue" 5 undefined(5是我之前输入的值)所以你可以看到,当我之前更改输入时,它很好地保留了存储中的值但是计算价值没有自我更新......

Ans 现在,当我更改输入的值时,我的控制台日志是这样"inputValue" 7 5的,所以它可以正常工作,因为我希望它从一开始就可以工作......

我做错了什么?为什么在第一次加载时计算值没有反应?

谢谢你的回答...

4

4 回答 4

1

我认为解决这个问题的最好方法是用一个观察者存储一个局部变量,然后在本地改变时更新vuex:

在您的组件上:

<input type="number" v-model="value">

data() {
    return {
        value: ''
    };
},

computed: {
    ...mapGetters({
        inputValue: 'getInputValue'
    })
}

watch: {
    value(value){
        this.$store.dispatch('setInputValue', value);
    },

    inputValue(value) {
        console.log('inputValue', value);
    }
},

created() {
    // set the initial value to be the same as the one in vuex
    this.value = this.inputValue;
}
于 2019-07-11T10:06:08.367 回答
0

模板中有一些小错误。应该是这样的:

<input type="number" :value="inputValue" @change="$store.dispatch('setInputValue', $event.target.value)">

我已经this.在几个地方删除了,并:在前面放了一个value。一旦我进行了这些更改,一切都会按预期工作。这this.$store导致我使用 Vue 2.6.10 出现控制台错误。

我要补充一点,您正在使用该change事件。这是标准的 DOMchange事件,在字段模糊之前不会触发。因此,如果您只是开始输入,您将不会看到控制台中发生任何事情。input如果您希望它在每次击键时更新,您最好使用它。或者,您可以使用v-modelgetter 和 setter(请参阅https://vuex.vuejs.org/guide/forms.html#two-way-computed-property)。

我的怀疑是,当您重新加载触发更改事件的页面时,因为它模糊了该字段。

于 2019-07-11T10:40:09.530 回答
0

好的,所以...我发现了问题,它与我的示例无关,我无法真正解释原因,但我会尝试解释如何:

在我的商店里,我有下一个方法:

mutations: {
    deleteAppValues(state) {
        state.appValues = null;
    }
}

我在注销时使用了这个,或者当用户第一次进入页面并且没有登录时......那么发生了什么?

  1. User第一次加载页面,store初始化很好,索引inputValue初始化为null值,所以存在...
  2. ...但是由于未登录用户,我销毁了商店,所以现在 inputValue 不等于 null,它只是不存在...
  3. 尝试mapGetters在不存在的东西上使用,反应将不起作用,所以如果我发送更改,将创建存储键,但由于 mapGetters 是用不存在的键初始化的,它不会监听反应...
  4. 重新加载页面后,密钥现在存在于商店中,因此可以将吸气剂附加到它上面,所以现在一切正常......

这正是我的代码出了什么问题的解释......所以为了让它正常工作,我只是将我的破坏突变更改为:

mutations: {
    deleteAppValues(state) {
        state.appValues = {
            inputValue: null,
        };
    }
}

像这样,存储对象的 inputValue 键将始终存在,因此 getter 不会失去反应性......

我试图提出一个简单简洁的问题,但这让我忘记了代码中不好的部分,抱歉。

于 2019-07-12T09:03:12.897 回答
0

请看一下这个示例:https ://codesandbox.io/s/vuex-store-ne3ol

您的错误是,您this在模板中使用关键字。不应该this在模板代码中使用。

<input
      type="number"
      value="inputValue"
      @change="$store.dispatch('setInputValue', $event.target.value)"
    >

额外提示:如果您可以使用 getter 返回默认状态,则使用 getter 返回默认状态是多余mapState的。

于 2019-07-11T10:38:46.157 回答