首页 > 编程笔记 > JavaScript笔记
阅读:4
Vuex的基本用法(附带实例)
在项目中使用 Vuex 来进行多个组件之间共享状态数据的管理,首先要下载其对应的工具包:
一般会在 src 目录下创建 store 子目录,并在子目录中创建 index.js 文件,使用 Vuex 提供的 createStore 函数来创建 store 对象,并暴露 store 对象。
src/store/index.js 文件代码如下:
接着需要将 store 对象在 main.js 文件中引入,并通过 store 配置项进行配置:
下面将 App 组件中的 count 定义到 state 对象中,将 CountShow 组件中的计算属性 oddOrEven 定义到 getters 对象中,将直接更新 count 的 increment 和 decrement 函数定义到 mutations 对象中,将包含逻辑处理的 incrementIfOdd 函数和包含异步定时器的 incrementAsync 函数定义到 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 方法的语法为:
commit 方法的语法为:
后面的操作就是在组件中通过 store 对象来读取状态数据和更新状态数据了,先来介绍一下 store 对象的相关语法。
通过 Vuex 提供的统一函数 useStore 来得到 store 对象:
通过 store 对象的 state 属性对象来读取某个状态数据,通过 store 对象的 getters 属性对象来读取某个计算属性数据。
要想更新状态数据,可以通过 store 对象的 commit 方法触发 mutation 方法执行,也可以通过 store 对象的 dispatch 方法触发 action 方法执行。store 对象的 commit 和 dispatch 方法的语法与上面介绍的是一样的:
首先改造 Counter 组件,不需要定义 count 数据,也不需要定义更新 count 数据的函数,这些都转移到了 Vuex 中,而且不需要向 CountShow 和 CountUpdate 组件标签传递属性,它们自己直接与 Vuex 通信就可以了。
然后改造 CountShow 组件,可以通过 Vuex 提供的 useStore 函数得到 store 对象,通过 store 对象的 state 对象属性和 getters 对象属性得到 count 和 oddOrEven。
最后改造 CountUpdate 组件,先得到 store 对象,然后在按钮的点击回调中调用 store 的 commit 方法或 dispatch 方法来触发 Vuex 的 mutation 方法或 action 方法的执行,只需要修改 JavaScript 代码。
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)
- 第 1 个参数为要触发执行的 action 方法的名称;
- 第 2 个参数是可选的,为要传递给 action 方法的数据,其会自动传递为 action 方法的第 2 个参数。
commit 方法的语法为:
commit(mutationName, data)
- 第 1 个参数为要触发执行的 mutation 方法的名称;
- 第 2 个参数是可选的,为要传递给 mutation 方法的数据,其会自动传递为 mutation 方法的第 2 个参数。
后面的操作就是在组件中通过 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 数据更新后,开发者调试工具会记录并显示最新的结果,调试页面如下图所示。