首页 > 编程笔记 > JavaScript笔记 阅读:4

Vuex的基本用法(附带实例)

在项目中使用 Vuex 来进行多个组件之间共享状态数据的管理,首先要下载其对应的工具包:
npm install vuex
然后要创建 store 对象,并配置其 4 个基本的对象:state、getters、mutations 和 actions。

一般会在 src 目录下创建 store 子目录,并在子目录中创建 index.js 文件,使用 Vuex 提供的 createStore 函数来创建 store 对象,并暴露 store 对象。

src/store/index.js 文件代码如下:
import { createStore } from 'vuex';

// 创建 store 对象,并配置 state、getters、mutations 和 actions 对象
const store = createStore({
  // 包含n个状态数据属性的对象
  state: { },
  // 包含n个基于state的计算属性的对象
  getters: { },
  // 包含n个直接更新状态数据的方法的对象
  mutations: { },
  // 包含n个执行同步或异步操作后间接更新状态数据的方法的对象
  actions: { }
});

// 默认暴露 store 对象
export default store;

接着需要将 store 对象在 main.js 文件中引入,并通过 store 配置项进行配置:
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';

createApp(App).use(store).mount('#app');

下面将 App 组件中的 count 定义到 state 对象中,将 CountShow 组件中的计算属性 oddOrEven 定义到 getters 对象中,将直接更新 count 的 increment 和 decrement 函数定义到 mutations 对象中,将包含逻辑处理的 incrementIfOdd 函数和包含异步定时器的 incrementAsync 函数定义到 actions 对象中,实现代码如下:
import { createStore } from 'vuex';
// 创建 store 对象,并配置 state、getters、mutations 和 actions 对象
const store = createStore({
  // 包含n个状态数据属性的对象
  state: {
    count: 0,
  },
  // 包含n个基于state的计算属性的对象
  getters: {
    oddOrEven(state) {
      return state.count % 2 === 1 ? '奇数' : '偶数';
    },
  },
  // 包含n个直接更新状态数据的方法的对象
  mutations: {
    increment(state, num) {
      state.count += num;
    },
    decrement(state, payload) {
      state.count -= payload;
    },
  },
  // 包含n个在执行同步或异步操作后间接更新状态数据的方法的对象
  actions: {
    incrementIfOdd(context, num) {
      if (context.state.count % 2 === 1) {
        context.commit('increment', num);
      }
    },
    incrementAsync({ commit }, num) {
      setTimeout(() => {
        commit('increment', num);
      }, 1000);
    },
  },
});
// 默认暴露 store 对象
export default store;
下面依次说明 state、getters、mutations 和 actions 对象。
1) state 对象比较简单,将共享数据 count 添加为 state 对象的属性,并指定需要显示的初始值为 0。

2) getters 对象中的计算属性接收一个参数作为当前 state 对象,返回根据 state 中数据计算的结果。

3) mutations 对象中的 mutation 方法接收的参数个数不是固定的,第 1 个参数固定为当前 state 对象,第 2 个参数是可选的,是 commit 方法执行时指定的数据(第 2 个参数)。关于第 2 个参数的命名说明:一是固定的名称 payload,二是根据数据的意义来取特定的名称,比如增加的数量,可以命名为 num。

4) actions 对象中的 action 方法接收的参数个数也不是固定的,第 1 个参数固定为包含 state 属性对象、commit 方法、dispatch 方法的 context 对象,第 2 个参数是可选的,为 dispatch 方法执行时指定的数据(第 2 个参数)。在 action 方法中我们可以执行一些复杂逻辑或异步操作,当有了结果后,调用 context 对象的 commit 方法触发对应的 mutation 方法调用来更新状态数据。当然在声明形参时,可以直接对 context 对象进行解构,解构出 commit、state 和 dispatch,至于解构出谁,就看需要谁了。

这里需要对 commit 和 dispatch 方法的使用做一个说明。dispatch 方法的语法为:
dispatch(actionName, data)

commit 方法的语法为:
commit(mutationName, data)

后面的操作就是在组件中通过 store 对象来读取状态数据和更新状态数据了,先来介绍一下 store 对象的相关语法。

通过 Vuex 提供的统一函数 useStore 来得到 store 对象:
import { useStore } from 'vuex';
// 得到 store 对象
const store = useStore();

通过 store 对象的 state 属性对象来读取某个状态数据,通过 store 对象的 getters 属性对象来读取某个计算属性数据。
// 通过 store 对象的 state 属性对象来读取某个状态数据
const xxx = store.state.xxx;
// 通过 store 对象的 getters 属性对象来读取某个计算属性数据
const yyy = store.getters.yyy;

要想更新状态数据,可以通过 store 对象的 commit 方法触发 mutation 方法执行,也可以通过 store 对象的 dispatch 方法触发 action 方法执行。store 对象的 commit 和 dispatch 方法的语法与上面介绍的是一样的:
// 通过 store 对象的 commit 方法触发 mutation 方法执行
store.commit(mutationName, data);
// 通过 store 对象的 dispatch 方法触发 action 方法执行
store.dispatch(actionName, data);
最后依次改造组件中的代码,利用 Vuex 的 store 对象来读取或更新其中的状态数据 count。这里需要改造 3 个组件。

首先改造 Counter 组件,不需要定义 count 数据,也不需要定义更新 count 数据的函数,这些都转移到了 Vuex 中,而且不需要向 CountShow 和 CountUpdate 组件标签传递属性,它们自己直接与 Vuex 通信就可以了。
<template>
  <div>
    <count-show/>
    <hr />
    <count-update/>
  </div>
</template>

<script setup>
import CountShow from './CountShow.vue';
import CountUpdate from './CountUpdate.vue';
</script>

然后改造 CountShow 组件,可以通过 Vuex 提供的 useStore 函数得到 store 对象,通过 store 对象的 state 对象属性和 getters 对象属性得到 count 和 oddOrEven。
<template>
  <div>
    点击次数为:{{ store.state.count }},当前次数为:
    {{ store.getters.oddOrEven }}
  </div>
</template>

<script setup>
import { useStore } from 'vuex';
// 得到 store 对象
const store = useStore();
</script>

最后改造 CountUpdate 组件,先得到 store 对象,然后在按钮的点击回调中调用 store 的 commit 方法或 dispatch 方法来触发 Vuex 的 mutation 方法或 action 方法的执行,只需要修改 JavaScript 代码。
<script setup>
import { ref } from 'vue';
import { useStore } from 'vuex';
const num = ref(1);

// 得到 store 对象
const store = useStore();

const clickIncrement = () => {
  // 触发名为 increment 的 mutation 方法的执行,并传递 num 值
  store.commit('increment', num.value);
};

const clickDecrement = () => {
  // 触发名为 decrement 的 mutation 方法的执行,并传递 num 值
  store.commit('decrement', num.value);
};

const clickIncrementIfOdd = () => {
  // 触发名为 incrementIfOdd 的 action 方法的执行,并传递 num 值
  store.dispatch('incrementIfOdd', num.value);
};

const clickIncrementAsync = () => {
  // 触发名为 incrementAsync 的 action 方法的执行,并传递 num 值
  store.dispatch('incrementAsync', num.value);
};
</script>
至此,所有代码编写完成,我们可以运行项目并测试功能。可以打开 Vue 开发者调试工具,在调试工具栏中选择 Vuex,就可以看到 Vuex 管理的 state 和 getters 数据了,并且在 state 数据更新后,开发者调试工具会记录并显示最新的结果,调试页面如下图所示。

相关文章