目录

一、Vuex

1.安装 Vuex

2.创建 Store

3.在 Vue 实例中使用 Store

4.在组件中使用 Vuex

二、Pinia

1.安装Pinia

2.定义Store

3.使用Store

4.数据持久化

三、Redux

1.安装依赖

2.创建Store

3.编写Redux配置

4.在React组件中使用全局Store

具体示例

注意事项

四、总结


前言:前端数据存储工具中,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和组件,以能够读取和更新状态。

      四、总结

      VuexPiniaRedux
      适用框架Vue.jsVue.js(特别是Vue 3)跨框架(常用于React,但也适用于Vue.js等)
      设计理念为Vue.js设计,提供全局状态管理Vuex的升级版,基于Vue 3的Composition API设计独立的状态管理库,遵循单项数据流原则
      核心概念Store、state、mutations、actions、getters、modulesStore、state、getters、actionsStore、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项目,提供简洁的状态管理解决方案适用于需要复杂状态管理和异步处理的大型应用,跨框架使用

      若文章对你有帮助,点赞、收藏加关注吧!

      Logo

      魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

      更多推荐