通过突变(Mutations)修改状态

到目前为止,您已经了解了如何从 Vuex 存储中读取数据,包括直接访问状态(state)和使用 getter。但为了真正改变存储的状态,Vuex 支持突变(mutations)的想法。突变是您在 store 中定义的处理状态变化的方法。因此,例如,您的组件不是简单地在状态中设置新值,而是要求存储执行突变(mutation),然后存储自行处理该逻辑。

这是一个简单的例子:

state: {
    totalCats: 5,
    name:'Lindy'
},
mutations: {
    newCat(state) {
        state.totalCats++;
    },
    setName(state, name) {
        state.name = name;
    }
}

在前面的代码片段中,store 的状态有两个值:totalCats 和 name。存在两个突变(mutations)可以让您更改这些值。所有突变都会传递一个 state 对象,该对象使您可以直接访问读取和更改值。第一个突变 newCat 只是增加了 totalCats 值。第二个突变 setName 显示了带有参数的突变示例。在这种情况下,您可以使用 setName 来更改存储中的名称值。

为了执行 mutation,您的组件将使用 commit 方法。例如,请参阅以下内容:

$store.commit('newCat');
$store.commit('setName', 'Raymond');

如果将多个值作为对象而不是简单值传递,则还可以传递多个值。在下一个练习中,您将有机会练习构建自己的突变(mutations)。

练习 9.04:处理突变(Mutations)

在本练习中,您将构建一个使用突变(mutations)来修改 Vuex 中的状态(state)数据的应用程序。搭建一个新应用程序,准备好后,打开位于 store/index.js 中的 store 文件。您的 store 将在某种程度上基于前面的示例。

要访问本练习的代码文件,请参阅 https://packt.live/3kcARiN

  1. 定义一个 totalCats 状态变量和名称状态值,然后定义三个突变来使用它们——一个突变用于增加猫的数量,一个突变用于减少猫的数量,最后一个突变用于设置名称:

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        state: {
            totalCats:5,
            name: "Lindy"
        },
        mutations: {
            adoptCat(state) {
                state.totalCats++;
            },
            placeCat(state) {
                if(state.totalCats > 0) state.totalCats--;
            },
            setName(state, name) {
                state.name = name;
            }
        }
    })

    接下来,您将构建一个简单的界面来使用该 store。该模板需要有一个 UI 来报告猫的名称和数量。您还需要一个文本字段和按钮来处理名称更新。

  2. 打开 App.vue 并更新它以包括从 store 输出当前值以及提供一个简单的表单以允许更新:

    <template>
        <div id="app">
            <h1>About Me</h1>
            <p>
                My name is {{ $store.state.name }} and
                I have {{ $store.state.totalCats }} cats.
            </p>
            <p>
                <input v-model="newName">
                <button @click="setName" :disabled="!newName">Update Name</button>
            </p>
            <Cat/>
        </div>
    </template>
    
    <script>
    import Cat from './components/Cat.vue'
    
    export default {
        name: 'app',
        components: {
            Cat
        },
        data() {
            return {
                newName:''
            }
        },
        methods: {
            setName() {
                if(this.newName) {
                    this.$store.commit('setName', this.newName);
                    this.newName = '';
                }
            }
        }
    }
    </script>
  3. 构建 Cat 组件。该组件将有简单的按钮来执行我们定义的突变,以增加和减少猫的数量:

    <template>
        <div>
            <button @click="addCat">More Cats!</button>
            <button @click="removeCat">Less Cats :(</button>
        </div>
    </template>
    
    <script>
    export default {
        name: 'Cat',
        methods: {
            addCat() {
                this.$store.commit('adoptCat');
            },
            removeCat() {
                this.$store.commit('placeCat');
            }
        }
    }
    </script>

完成后,像以前一样使用 npm run serve 启动您的应用程序,并在浏览器中打开显示的 URL。您的应用程序应该如下所示:

image 2023 10 16 21 48 28 610
Figure 1. Figure 9.5: Vue application with mutation support

虽然这是一个微不足道的练习,但有一些重要的事情需要注意。首先,请注意根组件和子组件与存储交互时都没有问题。您的组件层次结构可能非常深,而且它只是正常工作。其次,请注意 Vue 应用程序如何变得更简单,因为处理数据的逻辑位于存储中。我们使用的两个组件只是显示数据并处理将突变调用传递给存储。如果我们的逻辑需要更新,我们可以在 store 中处理它,并且所有内容都会正确更新。

到目前为止,您已经了解了如何以即时、同步的方式实施对 store 的更改。您现在将学习如何处理异步更新。