前端数据存储常用工具Vuex、Pinia、Redux详解
作者:前端绘梦师
前言:
前端数据存储工具中,Vuex、Pinia和Redux存储是常用工具,它们各自具有不同的特点和适用场景。
一、Vuex
1.安装 Vuex
(1)使用 npm 或 yarn 安装 Vuex
安装:npm i vuex
yarn i vuex
2.创建 Store
(1)创建 store 文件夹和文件
在项目的 src
目录下,创建一个名为 store
的文件夹。在 store
文件夹中,创建一个 index.js
文件。
(2)引入 Vuex 并创建 Store 实例
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); const store = new Vuex.Store({ // 数据 state: { count: 0, }, // store的计算属性 getters: {}, // 改变状态的唯一方法 同步函数 mutations: {}, // actions类似于mutation 可包含异步函数 actions: {}, // Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter,甚至是嵌套子模块。 modules: {} }) export default store;
3.在 Vue 实例中使用 Store
(1)在 main.js 中引入 Store
在项目的入口文件 main.js
中,引入刚才创建的 Store 实例,并将其传递给 Vue 构造函数。
import Vue from 'vue' // 引入vue import App from './App.vue' // 引入App.vue import store from './store' new Vue({ router, store, render: h => h(App) }).$mount('#app')
4.在组件中使用 Vuex
(1)访问状态(State)
在组件中,可以通过 this.$store.state
访问 Vuex 中的状态。
export default { computed: { count() { return this.$store.state.count; } } }
(2)提交变更(Mutations)
在组件中,可以通过 this.$store.commit()
方法提交变更。
export default { methods: { increment() { this.$store.commit('increment'); } } }
(3)执行异步操作(Actions)
在组件中,可以通过 this.$store.dispatch()
方法执行异步操作。
export default { methods: { asyncIncrement() { this.$store.dispatch('asyncIncrement'); } } }
(4)使用 Getter
Getter 用于从 state 中派生出一些状态。在组件中,可以通过 this.$store.getters
访问 Getter。例如:
export default { computed: { doubleCount() { return this.$store.getters.doubleCount; } } }
二、Pinia
1.安装Pinia
安装:npm install pinia
2.定义Store
(1)在项目的src
目录下创建一个stores
文件夹(如果尚未存在),用于存放多个Store文件。
(2)在stores
文件夹中创建一个新的Store文件,例如cart.js
。
(3)使用defineStore
函数来定义一个Store。需要指定Store的唯一名称,并提供一个包含state
、getters
和actions
等属性的对象来定义Store的内容。
import { defineStore } from 'pinia'; export const useCartStore = defineStore('cart', { state: () => ({ cartList: [], // 购物车列表数组 // 其他状态... }), getters: { allCount: (state) => state.cartList.reduce((total, goods) => total + goods.count, 0), // 计算所有商品的总数量 allPrice: (state) => state.cartList.reduce((total, goods) => total + goods.price * goods.count, 0), // 计算所有商品的总价格 // 其他getter... }, actions: { addCart(goods) { // 添加商品到购物车的逻辑 }, deleteCart(goodsId) { // 删除购物车中商品的逻辑 }, // 其他action... }, });
3.使用Store
(1)在需要使用Store的Vue组件中,通过import
语句导入相应的Store函数。
(2)使用Store函数来获取Store实例,并通过这个实例访问状态数据或调用方法。
<template> <!-- 使用Store中的数据 --> <div>购物车商品总数:{{ cartStore.allCount }}</div> </template> <script setup> import { useCartStore } from '@/stores/cart'; const cartStore = useCartStore(); // 可以通过cartStore访问状态数据或调用方法 </script>
4.数据持久化
(1)如果希望在页面刷新或关闭后仍能保留Store中的数据,可以使用pinia-plugin-persistedstate
插件来实现数据持久化。
(2)安装插件
运行命令:
npm install pinia-plugin-persistedstate
(3)在项目的入口文件(如main.js
或main.ts
)中,导入并使用该插件。
import { createApp } from 'vue'; import { createPinia } from 'pinia'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; import App from './App.vue'; const app = createApp(App); const pinia = createPinia(); pinia.use(piniaPluginPersistedstate); // 使用持久化插件 app.use(pinia); app.mount('#app');
(4)在定义Store时,通过传入{ persist: true }
选项来启用持久化功能。
export const useCartStore = defineStore('cart', { // ...state, getters, actions等定义 }, { persist: true }); // 启用持久化
三、Redux
state:存储应用的状态。
action:表示状态变化的对象。
reducer:纯函数,用于根据action更新状态。
middleware:中间件,用于处理异步逻辑和副作用。
1.安装依赖
在项目的根目录下,运行npm install redux react-redux @reduxjs/toolkit
命令来安装Redux及其相关依赖。
安装:npm install redux
2.创建Store
(1)在项目的src
目录下创建一个store
文件夹(如果尚未存在),用于存放Store相关的文件。
(2)在store
文件夹中创建一个index.js
文件,用于组合所有子模块的Store,并导出全局Store。
(3)在store
文件夹中创建一个modules
文件夹,用于存放多个子Store模块。
(4)在modules
文件夹中创建具体的子Store模块文件,例如counterStore.js
。
3.编写Redux配置
(1)在子Store模块文件中,使用createSlice
函数创建存储对象。需要传入一个配置对象,包括name
(指定存储器名称)、initialState
(指定初始化数据)和reducers
(指定修改数据的方法)。
(2)导出操作数据的行为函数(actions)和reducer函数。
(3)在store/index.js
文件中,使用configureStore
函数将所有子模块的Store组合在一起,并导出全局Store。
4.在React组件中使用全局Store
(1)在项目的入口文件(如index.js
或App.js
)中,使用Provider
组件将全局Store注入到React应用中。
(2)在需要使用全局状态的React组件中,使用useSelector
函数从Store中读取状态数据。
(3)使用useDispatch
函数获取dispatch方法,通过执行操作状态函数(actions)并传入参数来创建action对象,然后使用dispatch方法提交action以修改状态。
具体示例
以下是一个简单的Redux使用示例,包括创建Store、定义actions和reducer、在React组件中使用Store等步骤:
// store/modules/counterStore.js
import { createSlice } from "@reduxjs/toolkit"; const counterStore = createSlice({ name: "counter", initialState: { count: 0 }, reducers: { increment(state) { state.count++; }, decrement(state) { state.count--; }, addToNum(state, action) { state.count = state.count + action.payload; }, }, }); export const { increment, decrement, addToNum } = counterStore.actions; export default counterStore.reducer;
// store/index.js
import { configureStore } from "@reduxjs/toolkit"; import counterReducer from "./modules/counterStore"; const store = configureStore({ reducer: { counter: counterReducer, }, }); export default store;
import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import store from "./store"; import { Provider } from "react-redux"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <Provider store={store}> <App /> </Provider> );
import { useSelector, useDispatch } from "react-redux"; import { increment, addToNum } from "./store/modules/counterStore"; export default function App() { const { count } = useSelector((state) => state.counter); const dispatch = useDispatch(); function countIncrement() { dispatch(increment()); } function add20() { dispatch(addToNum(20)); } return ( <div> <div>{count}</div> <button onClick={countIncrement}>+1</button> <button onClick={add20}>+20</button> </div> ); }
注意事项
Redux中的状态是单向流动的,只能通过dispatch action来更新状态,不能直接修改状态。
使用Redux Toolkit可以简化Redux的配置和管理,推荐在新项目中使用。
在React组件中使用Redux时,要确保正确连接Store和组件,以能够读取和更新状态。
四、总结
Vuex | Pinia | Redux | |
---|---|---|---|
适用框架 | Vue.js | Vue.js(特别是Vue 3) | 跨框架(常用于React,但也适用于Vue.js等) |
设计理念 | 为Vue.js设计,提供全局状态管理 | Vuex的升级版,基于Vue 3的Composition API设计 | 独立的状态管理库,遵循单项数据流原则 |
核心概念 | Store、state、mutations、actions、getters、modules | Store、state、getters、actions | Store、state、action、reducer、middleware、store enhancer |
状态修改方式 | 使用mutations进行同步修改,actions处理异步逻辑 | 使用actions直接修改状态,actions支持异步操作 | 通过action触发reducer进行纯函数式的状态更新 |
API复杂度 | API丰富,功能全面,但相对复杂 | API简洁,易于使用,与Vue 3的Composition API紧密结合 | API较为抽象,需要理解单向数据流和纯函数的概念 |
异步处理 | 通过actions调用mutations实现 | actions直接支持异步操作 | 通过中间件(如redux-thunk、redux-saga)处理异步逻辑 |
插件和扩展 | 提供插件系统,可以扩展功能 | 可以通过插件扩展功能,生态逐渐完善 | 依赖第三方中间件和库进行扩展 |
持久化存储 | 可以使用插件(如vuex-persistedstate)实现 | 可以使用插件(如pinia-plugin-persistedstate)实现 | 可以使用redux-persist实现持久化存储 |
开发者工具 | 提供官方开发者工具,方便调试和监控状态变化 | 提供官方开发者工具,支持Vue Devtools | 提供强大的开发者工具,如Redux DevTools |
学习曲线 | 对于Vue.js开发者较为友好,但概念较多,学习曲线较陡 | API简洁,易于上手,适合Vue 3项目 | 需要理解单向数据流和纯函数的概念,学习曲线较陡 |
适用场景 | 适用于Vue.js项目,特别是中小型项目 | 适用于Vue 3项目,提供简洁的状态管理解决方案 | 适用于需要复杂状态管理和异步处理的大型应用,跨框架使用 |
总结
到此这篇关于前端数据存储常用工具Vuex、Pinia、Redux的文章就介绍到这了,更多相关前端数据存储Vuex、Pinia、Redux内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!