vue2(Vuex)、vue3(Pinia)、react(Redux)状态管理

vue2状态管理Vuex

Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它使用集中式存储管理应用的所有组件的状态,以及规则保证状态只能按照规定的方式进行修改。

  • State(状态):Vuex 使用单一状态树,即一个对象包含全部的应用层级状态。这个状态树对应着一个应用中的所有状态。
  • Getters(获取器):Getters 允许你在模板中计算状态。相当于组件中的计算属性。可以对 state 中的数据进行处理和过滤。
  • Mutations(变更):Mutations 是 Vuex 修改状态的唯一方式,它们是同步事务。每个 mutation 都有一个字符串类型的事件类型 (type) 和 一个回调函数,该回调函数接受 state 作为其第一个参数。
  • Actions(动作):Actions 类似于 Mutations,不同之处在于它们是异步的。Actions 提交 Mutations 来修改状态。Actions 可以包含任意异步操作。
  • modules(模块):Vuex 允许将 store 分割成模块,每个模块都有自己的 state、mutations、actions、getters。

辅助函数:便于在组件中使用 Vuex 的功能

  • mapState: 将 store 中的 state 映射为组件的计算属性。
  • mapGetters: 将 store 中的 getters 映射为组件的计算属性。
  • mapMutations: 将 store 中的 mutations 映射为组件的方法。
  • mapActions: 将 store 中的 actions 映射为组件的方法。

1、创建vue2项目

安装脚手架:npm install -g @vue/cli
创建vue2项目:vue create vue2_myapp
(输入完命令后选择vue2)

2、安装Vuex依赖
在项目中使用npm或者yarn安装Vuex。

npm install vuex
yarn add vuex
npm install vuex@^3.5.0 --save(指定版本使用)

3、在src目录下创建store目录,在下面创建js用于存储Vuex(命名通常为index.js或者store.js)

// store.js
import Vue from 'vue';
import Vuex from 'vuex';
import modulesA from './modules/modulesA'Vue.use(Vuex);export default new Vuex.Store({state: {//存储公共数据count: 100,},  mutations: {// 定义修改state数据的方法increment(state) {state.count++;},decrement(state) {state.count--;},},actions: {// 使用异步的方式来触发mutations中的方法进行提交},getters: {// 获取状态的方法getCount: (state) => state.count,},modules: {// 注册拆分的模块a:{//namespaced: true,//可以直接在modulesA配置在中...modulesA}}
});

当项目比较复杂时,可以在src/store下增加module,将数据拆成模块,下面举一个moduleA示例

// moduleA.js
import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);//注意此处是导出一个模块不是new一个新vuex
export default{namespaced: true,state: {//存储公共数据countA: 200,},  mutations: {// 定义修改state数据的方法incrementA(state) {state.countA++;},decrementA(state) {state.countA--;},},actions: {// 使用异步的方式来触发mutations中的方法进行提交incrementAsyncA({ commit }) {// 模拟一个异步操作,例如从 API 获取数据setTimeout(() => {commit('incrementA');}, 1000);},},getters: {// 获取状态的方法getCountA: (state) => state.countA,},
};

4、在main.js中引入store

import Vue from 'vue'
import App from './App.vue'
import store from './store/store';//引入store Vue.config.productionTip = falsenew Vue({render: h => h(App),store,//注册store
}).$mount('#app')

5、在组件中使用

<template><div><h2>Root Module</h2><p>Count from Root Module: <!-- 显示方式一:通过计算属性获取getter -->{{ rootCount }} || <!-- 显示方式二:直接获取state中的值 -->{{ $store.state.count }} || <!-- 显示方式三:通过...mapState(['count'])直接使用count -->{{ count }}</p><button @click="incrementRoot">增加模块 A 计数</button><button @click="decrementRoot">减少模块 A 计数</button><h2>Module A</h2><p>Count from Module A: <!-- 显示方式一:通过计算属性获取getter,需要配置namespaced -->{{ moduleACount }} || <!-- 显示方式二:通过在store中注册的模块直接使用modulesA的值 -->{{ $store.state.a.countA }}</p><button @click="incrementModuleA">增加模块 A 计数</button><button @click="decrementModuleA">减少模块 A 计数</button><button @click="incrementModuleAAsync">异步增加模块 A 计数</button></div>
</template><script>
import { mapState,mapMutations,mapActions } from 'vuex';export default {computed: {// 1、使用mapState方式获取数据// mapState使用方式一...mapState(['count']),// mapState使用方式二...mapState({rootCountMapState: 'count', // 将根模块的 'getCount' 映射为 'rootCount'moduleACount: 'a/getCountA', // 将模块 'a' 的 'getCountA' 映射为 'moduleACount'}),// 2、使用 mapGetters 辅助函数将模块中的 getters 映射到组件的计算属性    rootCount() {return this.$store.getters.getCount;},moduleACount() {return this.$store.getters['a/getCountA'];},},methods: {// 1、使用mapMutations获取mutations模块方式一...mapMutations({incrementRoot: 'increment', // 将根模块的 'increment' 映射为 'incrementRoot'decrementRoot: 'decrement', // 将根模块的 'decrement' 映射为 'decrementRoot'incrementModuleA: 'a/incrementA', // 将模块 'a' 的 'incrementA' 映射为 'incrementModuleA'decrementModuleA: 'a/decrementA', // 将模块 'a' 的 'decrementA' 映射为 'decrementModuleA'}),...mapActions({incrementModuleAAsync: 'a/incrementAsyncA', // 将 'a/incrementAsyncA' 映射为 'incrementModuleAAsync'}),// 使用 mapMutations 辅助函数将模块中的 mutations 映射到组件的方法二incrementRoot() {this.$store.commit('increment');},decrementRoot() {this.$store.commit('decrement');},incrementModuleA() {this.$store.commit('a/incrementA');},decrementModuleA() {this.$store.commit('a/decrementA');},},
};
</script>

示例效果图:
在这里插入图片描述

vue3状态管理Pinia

  • State(状态): 在 Store 中定义的数据,即应用程序的状态。状态可以是基本类型、对象、数组等。
  • Actions(操作): 在 Store 中定义的用于操作状态的函数。Actions 可以是同步或异步的,通过 this,你可以直接修改状态。如果 actions 返回一个 Promise,Pinia 将等待 Promise 完成,然后再继续执行其他代码。
  • Getter(获取器):获取器允许你从状态中派生出一些衍生数据,类似于计算属性。通过 getters,你可以在不直接修改状态的情况下获取和处理状态的数据。

1、创建项目(参见上面vue2,输入命令后选择vue3即可)
2、安装pinia

npm install pinia
yarn add pinia

3、在main.js中引入

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia';const app = createApp(App);app.use(createPinia());
app.mount('#app')

4、在src下创建store/index.js

import { defineStore } from 'pinia';export const useExampleStore = defineStore('example', {state: () => ({counter: 100,}),actions: {increment() {   this.counter++;console.log(this.counter);},decrement() {this.counter--;},},
});

5、在组件中通过setup()使用,下面列举了五种改变state数据的方式。

<!-- src/components/ExampleComponent.vue -->
<template><div><p>Counter: {{ exampleStore.counter }}</p><button @click="increment">Increment</button><button @click="decrement">Decrement</button></div>
</template><script setup>
import { useExampleStore } from '../store/index';// 组合式
const exampleStore = useExampleStore();const increment=()=>{// 方式一:在store的action中操作exampleStore.increment();// 方式二:直接在应用的组件中改变// exampleStore.counter++;// 方式三:使用$patch整体覆盖// exampleStore.$patch({//   counter:105// })// 方式四:使用$patch改变// exampleStore.$patch((state)=>{//   if(state.counter){//     state.counter++;//   }// })// 方式五:使用$state覆盖// exampleStore.$state ={//   counter:122// }
}
const decrement=()=>{// exampleStore.decrement();exampleStore.counter--;
}// 选项式
// export default {
//   setup() {
//     const exampleStore = useExampleStore();
//     return {
//       exampleStore,
//       increment: exampleStore.increment,
//       decrement: exampleStore.decrement,
//     };
//   }
// };
</script>

示例效果图:
在这里插入图片描述
Pinia与VueX区别:

  • Vuex 为vue2打造的,Pinia为vue3打造的
  • Pinia没有mutations,直接通过actions进行同步和异步操作,异步需要返回一个promise
  • Pinia 没有modules,设计更为分散,每个组件可以拥有自己的 Store。
  • Vuex 组件通过 mapState、mapMutations、mapActions 等辅助函数来访问存储库中的数据和操作。pinia通过setup 函数来引入和使用 Store,并通过 Store 的实例访问状态和操作。
  • Vuex 对 TypeScript 有良好的支持,但类型推断可能有时候会感觉有点繁琐。Pinia 是使用 TypeScript 编写的,提供了更好的 TypeScript 支持,可以更轻松地推断和利用类型信息。
  • vuex做数据持久化使用插件vuex-persistedstate,Pinia做数据持久化使用pinia-plugin-persist

react状态管理Redux

  • Provider:把父组件传递进来的store对象放入react 上下文中,这样connect组件就可以从上下文中获取到store对象
  • combineReducer:store.state进行分片管理,每个reducer管理state中的一部分。由于createStore只接受一个reducer,所以采用该方法生成一个最终的reducer
  • 中间件(Middleware):中间件是一个位于动作派发和 Reducer 之间的拦截层。它允许你在动作被派发到 Reducer 之前执行额外的逻辑。
  • State:整个 Redux 应用程序的状态,它是只读的。状态的更新是通过触发动作来创建新的状态,而不是直接修改原有状态。
  • action:更新state的状态时用。
  • dispatch:触发store修改state的命令,是createStore返回对象的一个方法
  • connect:从react上下文中取出store对象,订阅store.state的变化,当store state变化时调用自身的方法重新生成connect组件的state,被包装组件便会被重新渲染。不会感知到store的存在,dispatch在这里也是非必须的。
    connect的4个内置组件: 状态mapStateToProps、动作mapDispatchToProps、属性合并mergeProps 和 配置项options
  • 异步中间件:redux没有直接提供执行异步操作的方法,需要手动集成中间件,最常用异步实现的中间件有redux-thunkredux-saga

1、搭建react+ts项目

npm install -g create-react-app
npx create-react-app my-react-ts-app --template typescript

2、安装redux

npm install redux react-redux

3、在src下创建如下结构
src/
– – store/
– – – – index.ts
– – – – reducers/
– – – – – – index.ts
– – – – – – counterReducer.ts

// src/store/index.ts
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';const store = configureStore({reducer: rootReducer
});export default store;
// src/store/reducers/index.ts
// combineReducers 用于将多个 reducer 组合成一个根 reducer
import { combineReducers } from 'redux';
import counterReducer from './counterReducer';const rootReducer = combineReducers({counter: counterReducer,// 添加其他 reducer...
});export default rootReducer;
// src/store/reducers/counterReducer.ts// 从Redux中导入Action类型,用于定义动作对象
import { Action } from 'redux';// 定义动作类型的常量,以避免拼写错误
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';// Action Creators: 返回动作对象的函数
export const increment = (): Action => ({ type: INCREMENT });
export const decrement = (): Action => ({ type: DECREMENT });// Reducer函数:根据派发的动作更新状态
const counterReducer = (state = 0, action: Action): number => {switch (action.type) {case INCREMENT:// 当派发INCREMENT动作时,将当前状态加1return state + 1;case DECREMENT:// 当派发DECREMENT动作时,将当前状态减1return state - 1;case 'INCREMENTFIXED':return state + 5;default:// 如果动作类型不被识别,则返回当前状态return state;}
};// 将counterReducer作为模块的默认导出
export default counterReducer;

4、在index.tsx中引入

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
//引入redux
import { Provider } from 'react-redux';
import store from './store';const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement
);
root.render(<React.StrictMode><Provider store={store}><App /></Provider></React.StrictMode>);reportWebVitals();

5、在components中创建Counter.tsx

// src/components/Counter.tsx
import React from 'react';
import { connect } from 'react-redux';
import { increment, decrement } from '../store/reducers/counterReducer';interface CounterProps {count: number;increment: () => void;decrement: () => void;
}const Counter: React.FC<CounterProps> = ({ count, increment, decrement }) => {return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button><button onClick={decrement}>Decrement</button></div>);
};// 中间件mapStateToProps 函数将 Redux store 的状态映射到组件的属性。
const mapStateToProps = (state: { counter: number }) => ({count: state.counter,
});// 中间件mapDispatchToProps 对象将动作创建函数映射到组件的属性。
const mapDispatchToProps = {increment,decrement
};// connect 函数将组件连接到 Redux store,并将 mapStateToProps 和 mapDispatchToProps 的结果传递给组件
export default connect(mapStateToProps, mapDispatchToProps)(Counter);

示例效果图:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/243467.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性代数的学习和整理23:用EXCEL和python 计算向量/矩阵的:内积/点积,外积/叉积

目录 1 乘法 1.1 标量乘法(中小学乘法) 1.1.1 乘法的定义 1.1.2 乘法符合的规律 1.2 向量乘法 1.2.1 向量&#xff1a;有方向和大小的对象 1.2.2 向量的标量乘法 1.2.3 常见的向量乘法及结果 1.2.4 向量的其他乘法及结果 1.2.5 向量的模长&#xff08;长度&#xff0…

【极数系列】Flink环境搭建(02)

【极数系列】Flink环境搭建&#xff08;02&#xff09; 引言 1.linux 直接在linux上使用jdk11flink1.18.0版本部署 2.docker 使用容器部署比较方便&#xff0c;一键启动停止&#xff0c;方便参数调整 3.windows 搭建Flink 1.18.0版本需要使用Cygwin或wsl工具模拟unix环境…

RAMROM

RAM&#xff08;Random Access Memory&#xff09;&#xff0c;随机存取存储器&#xff0c;也叫主存&#xff0c;又称内存&#xff08;动态ROM&#xff09;&#xff0c;是与CPU直接交换数据的内部存储器。它可以随时读写&#xff08;刷新时除外&#xff09;&#xff0c;而且速度…

Flutter 自定义AppBar实现滚动渐变

1、使用ListView实现上下滚动。 2、使用Stack&#xff1a;允许将其子部件放在彼此的顶部&#xff0c;第一个子部件将放置在底部。所以AppBar&#xff0c;写在ListView下面。 3、MediaQuery.removePadding&#xff1a;当使用ListView的时候发现&#xff0c;顶部有块默认的Padd…

服务器数据恢复—服务器进水导致阵列中磁盘同时掉线的数据恢复案例

服务器数据恢复环境&#xff1a; 数台服务器数台存储阵列柜&#xff0c;共上百块硬盘&#xff0c;划分了数十组lun。 服务器故障&检测&#xff1a; 外部因素导致服务器进水&#xff0c;进水服务器中一组阵列内的所有硬盘同时掉线。 北亚数据恢复工程师到达现场后发现机房内…

链路聚合原理与配置

链路聚合原理 随着网络规模不断扩大&#xff0c;用户对骨干链路的带宽和可靠性提出了越来越高的要求。在传统技术中&#xff0c;常用更换高速率的接口板或更换支持高速率接口板的设备的方式来增加带宽&#xff0c;但这种方案需要付出高额的费用&#xff0c;而且不够灵活。采用…

【GitHub项目推荐--一个语音机器人项目】【转载】

推荐一个腾讯大佬开源的语音对话机器人&#xff1a;wukong-robot &#xff0c;悟空机器人在 GitHub 上斩获 3.2K 的 Star。 这是一个简单灵活的中文语音对话机器人项目&#xff0c;目的是让中国的开发者也能快速打造个性化的智能音箱&#xff0c;同时&#xff0c;该项目还是第…

JMeter 设置请求头信息的详细步骤

在使用 JMeter 的过程中&#xff0c;我们会遇到需要设置请求头信息的场景。比如&#xff1a; POST 传过去的 Body 数据是 json 格式的。需要填添加头信息&#xff1a;Content-Type&#xff1a;application/json。在 header 中用 token 来传用户的认证信息。 下面&#xff0c;…

编程语言MoonBit新增矩阵函数的语法糖

MoonBit更新 1. 新增矩阵函数的语法糖 新增矩阵函数的语法糖&#xff0c;用于方便地定义局部函数和具有模式匹配的匿名函数&#xff1a; fn init {fn boolean_or { // 带有模式匹配的局部函数true, _ > true_, true > true_, _ > false}fn apply(f, x) {f(x)}le…

【Qt Quick 项目(第一集Qt Quick UI 项目项目创建)】

# Qt Quick 项目 到底什么是Qt Qml、什么是Qt Quick、QtQuick应用程序与Qt Widget程序有何区别,为了让读者在学习QML之前有一个整体认识,这里先介绍几个Quick项目。 01 Qt Quick UI 项目

【江科大】STM32:(超级详细)定时器输出比较

文章目录 输出比较单元特点 高级定时器&#xff1a;均有4个通道 PWM简介PWM&#xff08;Pulse Width Modulation&#xff09;脉冲宽度调制输出比较通道PWM基本结构基本定时器 参数计算捕获/比较通道的输出部分详细介绍如下&#xff1a; 舵机介绍硬件电路 直流电机介绍&#xff…

CRM的定义、功能,以及国内外CRM系统排名

什么是客户关系管理? CRM是(客户关系管理)的缩写&#xff0c;是一个管理与客户关系的系统。CRM的主要功能是管理基本客户信息和购买历史的客户管理、分析潜在客户和新客户的客户分析、对询问的自动回复的响应以及通过电子邮件通讯和研讨会吸引客户。它是加强和维护与客户和潜…

proxy 代理的接口报错301问题

项目系统里仅仅这个接口报错&#xff0c;反向代理错误导致。 默认情况下&#xff0c;不接受运行在HTTPS上&#xff0c;且使用了无效证书的后端服务器。如果你想要接受&#xff0c;修改配置&#xff1a;secure: false&#xff08;简单意思&#xff1a;如果本地没有进行过https相…

算法第二十二天-最大数

最大数 题目要求 解题思路 今天的题目&#xff0c;让我们将一组数字重新组合&#xff0c;构成一个最大的整数。由于构成的整数非常大&#xff0c;所以返回结果需要字符串格式。 分析一下规律&#xff1a; 为了避免用int型或者long型越界&#xff0c;所以我们需要把数字先转换…

用ChatGPT教学、科研!大学与OpenAI合作

亚利桑那州立大学&#xff08;简称“ASU”&#xff09;在官网宣布与OpenAI达成技术合作。从2024年2月份开始&#xff0c;为所有学生提供ChatGPT企业版访问权限&#xff0c;主要用于学习、课程作业和学术研究等。 为了帮助学生更好地学习ChatGPT和大语言模型产品&#xff0c;AS…

计算机视觉工程师就业前景如何?

计算机视觉作为一门快速发展的技术领域&#xff0c;其就业前景非常广阔。以下是对计算机视觉就业前景的分析&#xff1a; 市场规模&#xff1a;计算机视觉行业的市场规模正在持续扩大。根据行业分析报告&#xff0c;预计全球计算机视觉市场规模将在2025年达到530亿美元&#xf…

C#,入门教程(35)——哈希表(Hashtable)的基础知识与用法

上一篇&#xff1a; C#&#xff0c;入门教程(34)——关于函数的参数之引用&#xff08;ref&#xff09;的一点知识与源程序https://blog.csdn.net/beijinghorn/article/details/125411351 有一段故事&#xff1a; King Log The frogs in the lake had an easy life doing ex…

k8s-helm

Helm: 什么是helm,在没有这个heml之前&#xff0c;deployment service ingress的作用就是通过打包的方式&#xff0c;把deployment service ingress这些打包在一块&#xff0c;一键式的部署服务&#xff0c;类似于yum 官方提供的一个类似于安全仓库的功能&#xff0c;可以实现…

linux docker-compose安装失败解决

1.去github下载到本地 https://github.com/docker/compose/releases/ 2.上传到linux 服务器 mv dokcer-compose-linux-x86_64 /usr/loacal/bin/docker-compose 3.给权限 chmod x /usr/local/bin/docker-compose 4.查看是否安装成功 docker-compose -version 5.卸载 …

074:vue+mapbox 加载here地图(影像瓦片图 v2版)

第074个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载here地图的影像瓦片图 v2软件版本。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共77行)相关API参考:专栏目标示例效果