Vuex 初体验 mutations actions

57 阅读1分钟

效果

动画.gif 组件A,B,C 同步修改和异步修改 Vuex state.count

使用

  1. npm install --save vuex@3.5.1
  2. Vue.use(Vuex) // 注册插件
new Vue({
// 注入store以实例,已让所有组件可以访问到store
  store,
  render: (h) => h(App),
}).$mount("#app");

创建一个store

提供三个同步函数,和三个异步函数

  1. 为什么mutations是同步的

在 Vuex 中,mutations 是同步的,这是因为 Vuex 的设计思想是将 state 的变化变得可追踪、可维护。在 Vuex 中,state 是唯一的数据源,只有通过 mutations 才能修改 state 的数据。将 mutations 设计为同步操作,可以保证在调用 mutations 时,store 中的 state 状态已经被更新。这样做可以使得我们可以跟踪每个 mutation 的操作,并且在 mutation 的回调函数中执行一些需要同步完成的操作。

import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);

// 等待duration
function delay(duration) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, duration);
  });
}

const store = new Vuex.Store({
  state: {
    count: 0,
  },
  // mutations(突变):定义同步函数
  mutations: {
    increase(state) {
      state.count++;
    },
    decrease(state) {
      state.count--;
    },
    // payLoad 为传的参数
    change(state, payLoad) {
      state.count = payLoad;
    },
  },
  actions: {
    async asyncIncrease(ctx) {
      await delay(1000);
      // 修改函数必须使用motations里面的方法,调用mutations里面的函数
      ctx.commit("increase");
    },
    async asyncDecrease(ctx) {
      await delay(1000);
      ctx.commit("decrease");
    },
    async asyncChange(ctx, payLoad) {
      await delay(1000);
      ctx.commit("change", payLoad);
    },
  },
});
export default store;

组件调用store的函数

组件C 为例:

<template>
    <div class="block">
        <p>input change number</p>
        <h1>
            {{ number }}
        </h1>
        <input v-model.number.trim="number" type="text" />
        <button @click="handleClick">submit</button>
        <button @click="handleAsyncClick">async submit</button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            number: null, // 声明number属性为响应式属性
        };
    },
    methods: {
        handleClick() {
            // 访问this.$store可以访问store实例, 通过commit调用同步函数
            this.$store.commit('change', this.number);
        },
            // 通过dispatch(派遣)调用异步函数
        handleAsyncClick() {
            this.$store.dispatch('asyncChange', this.number)
        }
    },
}
</script>