vue和react和uniapp的状态管理分别是什么,并且介绍和怎么使用
一、Vue 的状态管理
Vue 的状态管理方案主要有 Vuex(Vue2 主流)和 Pinia(Vue3 官方推荐,Vuex 的继任者),用于管理组件间共享的状态(如用户信息、全局配置等)。
1. Vuex(适用于 Vue2)
核心概念:
State
:存储全局状态的对象(唯一数据源)。Mutation
:修改状态的唯一方式(同步操作),必须是纯函数。Action
:处理异步操作(如接口请求),通过提交Mutation
修改状态。Getter
:类似计算属性,用于派生状态(可缓存结果)。Module
:将 store 拆分为多个模块(避免单一状态树过于庞大)。
使用步骤:
① 安装:npm install vuex --save
② 创建 store(src/store/index.js
)
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({// 状态state: {count: 0,user: null},// 同步修改状态mutations: {increment(state) {state.count++},setUser(state, userInfo) {state.user = userInfo}},// 异步操作actions: {// 模拟异步请求用户信息fetchUser({ commit }) {return new Promise(resolve => {setTimeout(() => {const user = { name: '张三', age: 20 }commit('setUser', user) // 提交 mutation 修改状态resolve(user)}, 1000)})}},// 派生状态getters: {doubleCount(state) {return state.count * 2}}
})export default store
③ 在 main.js 中挂载:
import Vue from 'vue'
import App from './App.vue'
import store from './store'new Vue({store, // 挂载后可通过 this.$store 访问render: h => h(App)
}).$mount('#app')
④ 在组件中使用:
<template><div><p>计数:{{ $store.state.count }}</p><p>翻倍计数:{{ $store.getters.doubleCount }}</p><button @click="handleIncrement">+1</button><button @click="handleFetchUser">获取用户</button></div>
</template><script>
export default {methods: {handleIncrement() {this.$store.commit('increment') // 调用 mutation},async handleFetchUser() {await this.$store.dispatch('fetchUser') // 调用 actionconsole.log(this.$store.state.user) // { name: '张三', ... }}}
}
</script>
2. Pinia(适用于 Vue3,推荐)
Pinia 简化了 Vuex 的设计(移除 Mutation
,支持 Vue3 的 Composition API),更轻量、易上手。
核心概念:
State
:存储状态(可直接修改,无需 mutation)。Action
:支持同步 / 异步操作,直接修改 state。Getter
:派生状态(同 Vuex)。
使用步骤:
① 安装:npm install pinia --save
② 创建 store(src/store/index.js
)
import { defineStore } from 'pinia'// 定义 store(id 需唯一)
export const useCounterStore = defineStore('counter', {state: () => ({count: 0,user: null}),getters: {doubleCount: (state) => state.count * 2},actions: {increment() {this.count++ // 直接修改 state},async fetchUser() {// 模拟异步请求const user = await new Promise(resolve => {setTimeout(() => resolve({ name: '李四', age: 22 }), 1000)})this.user = user // 直接修改 state}}
})
③ 在 main.js 中挂载:
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'const app = createApp(App)
app.use(createPinia()) // 挂载 Pinia
app.mount('#app')
④ 在组件中使用(支持 Options API 和 Composition API):
<template><div><p>计数:{{ counterStore.count }}</p><p>翻倍计数:{{ counterStore.doubleCount }}</p><button @click="counterStore.increment">+1</button><button @click="counterStore.fetchUser">获取用户</button></div>
</template><script setup>
import { useCounterStore } from './store'
const counterStore = useCounterStore() // 引入 store
</script>
二、React 的状态管理
React 本身没有官方状态管理库,需依赖第三方工具。主流方案有:Redux(经典)、Redux Toolkit(Redux 简化版)、Context + useReducer(轻量场景),以及 Zustand、Recoil 等新兴库。
1. Redux Toolkit(推荐,简化 Redux 用法)
Redux 核心是 “单一状态树”,通过 Action
(描述操作)和 Reducer
(处理状态变更)管理状态。Redux Toolkit 简化了 Redux 的模板代码。
核心概念:
Store
:存储全局状态的容器(唯一)。Slice
:包含state
、reducer
和action
的独立模块。Action
:描述 “要做什么” 的普通对象(由createSlice
自动生成)。Reducer
:根据 action 处理状态变更的纯函数。
使用步骤:
① 安装:npm install @reduxjs/toolkit react-redux --save
② 创建 slice(src/store/counterSlice.js
)
import { createSlice } from '@reduxjs/toolkit'// 初始状态
const initialState = {count: 0,user: null
}// 创建 slice(自动生成 action 和 reducer)
const counterSlice = createSlice({name: 'counter', // 模块名initialState,reducers: {// 同步修改increment: (state) => {state.count++ // Redux Toolkit 内部使用 Immer 库,支持“直接修改”写法},setUser: (state, action) => {state.user = action.payload // action.payload 为传入的参数}},// 处理异步 action(需配合 createAsyncThunk)extraReducers: (builder) => {builder.addCase(fetchUser.pending, (state) => {state.loading = true}).addCase(fetchUser.fulfilled, (state, action) => {state.user = action.payloadstate.loading = false})}
})// 导出同步 action
export const { increment, setUser } = counterSlice.actions// 定义异步 action(使用 createAsyncThunk)
import { createAsyncThunk } from '@reduxjs/toolkit'
export const fetchUser = createAsyncThunk('user/fetch', // action 类型名async () => {// 模拟接口请求const res = await new Promise(resolve => {setTimeout(() => resolve({ name: '王五', age: 25 }), 1000)})return res}
)// 导出 reducer
export default counterSlice.reducer
③ 创建 store(src/store/index.js
):
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './counterSlice'// 配置 store(自动集成中间件,无需手动配置)
export const store = configureStore({reducer: {counter: counterReducer // 注册 slice 的 reducer}
})
④ 在入口文件挂载(src/index.js
):
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import { Provider } from 'react-redux' // 提供 store 上下文
import { store } from './store'const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<Provider store={store}><App /></Provider>
)
⑤ 在组件中使用:
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux' // hooks 访问 store
import { increment, fetchUser } from './store/counterSlice'function Counter() {// 获取状态const { count, user } = useSelector(state => state.counter)// 获取 dispatch 方法const dispatch = useDispatch()return (<div><p>计数:{count}</p><button onClick={() => dispatch(increment())}>+1</button><button onClick={() => dispatch(fetchUser())}>获取用户</button>{user && <p>用户:{user.name}</p>}</div>)
}export default Counter
2. Context + useReducer(轻量场景)
对于简单项目,可使用 React 内置的 Context
和 useReducer
实现状态管理,无需引入第三方库。
import React, { createContext, useReducer, useContext } from 'react'// 1. 创建 Context
const CounterContext = createContext()// 2. 定义 reducer(处理状态变更)
function reducer(state, action) {switch (action.type) {case 'INCREMENT':return { ...state, count: state.count + 1 }case 'SET_USER':return { ...state, user: action.payload }default:return state}
}// 3. 创建 Provider 组件(提供状态和 dispatch)
export function CounterProvider({ children }) {const [state, dispatch] = useReducer(reducer, { count: 0, user: null })return (<CounterContext.Provider value={{ state, dispatch }}>{children}</CounterContext.Provider>)
}// 4. 自定义 hook 简化使用
function useCounter() {return useContext(CounterContext)
}// 5. 在组件中使用
function Counter() {const { state, dispatch } = useCounter()return (<div><p>计数:{state.count}</p><button onClick={() => dispatch({ type: 'INCREMENT' })}>+1</button></div>)
}// 6. 在入口组件中包裹
function App() {return (<CounterProvider><Counter /></CounterProvider>)
}
三、UniApp 的状态管理
UniApp 基于 Vue 语法,因此状态管理方案与 Vue 高度兼容,主流方案有:
- Vuex/Pinia:同 Vue 的使用方式(推荐,适合复杂项目)。
- 全局变量:通过
getApp().globalData
定义全局变量(适合简单场景)。 - 事件总线:通过
uni.$on
/uni.$emit
实现组件通信(适合跨组件消息传递)。
1. Vuex(UniApp 中最常用)
使用方式与 Vue2 中的 Vuex 一致,仅需注意 UniApp 的项目结构。
使用步骤:
① 在项目根目录创建 store
文件夹,新建 index.js
:
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({state: {token: '',userInfo: null},mutations: {setToken(state, token) {state.token = token// 可同步到本地存储(持久化)uni.setStorageSync('token', token)}},actions: {login({ commit }, userData) {// 模拟登录接口return new Promise(resolve => {setTimeout(() => {const token = 'xxx-token-xxx'commit('setToken', token)resolve(token)}, 1000)})}}
})export default store
② 在 main.js
中挂载:
import Vue from 'vue'
import App from './App'
import store from './store'Vue.prototype.$store = store // 挂载到 Vue 原型const app = new Vue({...App,store
})
app.$mount()
③ 在页面 / 组件中使用:
<template><view><button @click="handleLogin">登录</button></view>
</template><script>
export default {methods: {async handleLogin() {const token = await this.$store.dispatch('login', { username: 'test' })console.log('登录成功,token:', token)console.log('全局状态中的 token:', this.$store.state.token)}}
}
</script>
2. 全局变量(简单场景)
通过 getApp().globalData
定义全局变量,适合无需复杂逻辑的简单状态。
示例:
① 在 App.vue
中定义:
onLaunch() {// 初始化全局数据getApp().globalData = {theme: 'light',version: '1.0.0'}
}
② 在页面中使用:
<template><view>当前主题:{{ theme }}</view>
</template><script>
export default {data() {return {theme: ''}},onLoad() {// 读取全局变量this.theme = getApp().globalData.theme// 修改全局变量getApp().globalData.theme = 'dark'}
}
</script>
总结
- Vue:Vue2 用 Vuex,Vue3 推荐 Pinia(更简洁,支持 Composition API)。
- React:复杂项目用 Redux Toolkit,简单项目用 Context + useReducer。
- UniApp:优先使用 Vuex/Pinia(与 Vue 生态一致),简单场景可用全局变量或事件总线。
状态管理的核心是 “集中管理共享状态”,选择方案时需根据项目复杂度和团队熟悉度决定。