首页 > 解决方案 > VueX:为什么 vuex 存储数据不更新组件数据属性?

问题描述

在以下代码中,组件(app.vue)属性在更新存储计数器c2时不会更新incrementthis.$store.state.counter++;

我知道我可以通过使用c2ascomputed属性来解决这个问题,但我想知道为什么 Vuex 或 vue 不启动反应性,因为计数器的值是通过增量方法更新的。

Store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    counter: 0
  },
  mutation: {
    increment() {
      return this.$state.counter++;
    }
  }
});

应用程序.vue

<template>
  <div id="app">
    <button @click="increment">Increment</button>
    {{ c2 }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      c2: this.$store.state.counter
    };
  },
  methods: {
    increment() {
      this.$store.state.counter++;
    }
  }
};
</script>

谢谢

标签: vue.jsvuex

解决方案


Vuex 使用一种叫做“动作”的东西,它们看起来就像突变,但它们不是改变状态,而是提交突变。你不能像这样修改你的 Vuex 存储状态:

methods: {
  increment() {
    this.$store.state.counter++
  }
}

相反,您应该在商店内创建一个带有操作的操作对象:

actions: {
  increment (context) {
    context.commit('increment')
  }
}

现在,该代码是这样说的:“每当您派遣我(操作)时,在称为增量的突变内运行代码”,这意味着:“提交称为增量的突变”。

另一个重要的事情是您的组件方法称为“增量”。您应该将其修改为如下所示:

methods: {
  increment() {
    this.$store.dispatch('increment')
  }
}

现在,每当您调用此方法时,您将调度一个将提交突变的操作。

最后,为了让你的状态进入你的组件(至少是好方法)将使用mapStateVuex 提供的函数。

首先,在你的组件脚本标签中导入这个:

import { mapState } from 'vuex'

并创建一个这样的计算属性:

computed: mapState([
  'counter'
])

这将使您能够访问counter在商店状态中定义的属性。在这种情况下,您可以删除data()函数中的 return 语句并更改 html 以显示counter属性:

<template>
  <div id="app">
    <button @click="increment">Increment</button>
    {{ counter }}
  </div>
</template>

就是这样!


推荐阅读