全篇大概 4500 字(含代码),建议阅读时间 30min
📚 目录
一、Vuex 核心概念解析
1.1 什么是状态管理
在跨多组件的大型应用中,不同页面/组件需要共享和修改相同数据时,直接通过 Props/Event 传递会导致代码冗余和维护困难。Vuex 作为 集中式状态管理方案,通过统一存储和管理应用级状态,实现数据流的可预测性。
1.2 Vuex 五大核心概念
State
(状态)
单一数据源,所有组件共享的数据存储对象
// store/index.js
export default new Vuex.Store({
state: {
userInfo: null, // 用户信息
cartItems: [], // 购物车商品
themeColor: '#42b983' // 全局主题色
}
})
Getters
(派生状态)
基于 State 的计算属性,用于派生复杂数据
getters: {
totalPrice: state => {
return state.cartItems.reduce((sum, item) =>
sum + item.price * item.quantity, 0)
},
isLoggedIn: state => !!state.userInfo
}
Mutations
(同步修改)
唯一修改 State 的方法,必须是同步函数
mutations: {
SET_USER(state, user) {
state.userInfo = user
},
ADD_TO_CART(state, product) {
const item = state.cartItems.find(p => p.id === product.id)
item ? item.quantity++ : state.cartItems.push({...product, quantity: 1})
}
}
Actions
(异步操作)
处理异步逻辑后提交 Mutations
actions: {
async login({ commit }, credentials) {
const res = await uni.request({
url: '/api/login',
method: 'POST',
data: credentials
})
commit('SET_USER', res.data)
}
}
Modules
(模块化)
将复杂 Store 拆分为多个模块
// store/modules/cart.js
export default {
namespaced: true,
state: { items: [] },
mutations: { /* ... */ }
}
二、在 UniApp 中集成 Vuex
2.1 安装与配置
步骤 1:安装依赖
npm install vuex --save
步骤 2:创建 Store
结构
├── store/
│ ├── index.js # 主入口
│ ├── modules/ # 模块目录
│ │ └── user.js
│ └── types.js # Mutation 类型常量
步骤 3:初始化
Store
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user
}
})
步骤 4:挂载
到 UniApp
// main.js
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
store,
...App
})
app.$mount()
三、状态管理与数据共享实践
3.1 基础使用场景
场景 1:全局
用户状态管理
<!-- pages/user/login.vue -->
<script>
export default {
methods: {
handleLogin() {
this.$store.dispatch('user/login', {
username: 'test',
password: '123456'
}).then(() => {
uni.switchTab({ url: '/pages/home/index' })
})
}
}
}
</script>
场景 2:跨页面
共享购物车数据
// 组件中访问购物车
computed: {
cartItems() {
return this.$store.state.cart.items
},
total() {
return this.$store.getters['cart/totalPrice']
}
}
3.2 模块化高级实践
模块定义
// store/modules/user.js
export default {
namespaced: true,
state: () => ({
token: uni.getStorageSync('token') || null,
profile: null
}),
mutations: {
SET_TOKEN(state, token) {
state.token = token
uni.setStorageSync('token', token)
},
SET_PROFILE(state, user) {
state.profile = user
}
},
actions: {
async fetchProfile({ commit }) {
const { data } = await uni.$http.get('/user/profile')
commit('SET_PROFILE', data)
}
}
}
跨模块调用
// 在购物车模块中获取用户ID
actions: {
async loadCart({ rootState, commit }) {
const userId = rootState.user.profile.id
const res = await uni.$http.get(`/cart/${userId}`)
commit('INIT_CART', res.data)
}
}
3.3 持久化存储方案
使用 vuex-persistedstate
npm install vuex-persistedstate
// store/index.js
import createPersistedState from 'vuex-persistedstate'
export default new Vuex.Store({
plugins: [
createPersistedState({
key: 'my-app-store',
paths: ['user.token', 'settings.theme'],
storage: {
getItem: key => uni.getStorageSync(key),
setItem: (key, value) => uni.setStorageSync(key, value),
removeItem: key => uni.removeStorageSync(key)
}
})
]
})
四、最佳实践与性能优化
4.1 代码组织规范
// store/types.js
export const SET_USER = 'user/SET_USER'
export const ADD_PRODUCT = 'cart/ADD_PRODUCT'
// 使用常量代替字符串
mutations: {
[SET_USER](state, payload) { /* ... */ }
}
4.2 严格模式与调试
// 开发环境开启严格模式
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production'
})
4.3 性能优化策略
使用 mapState
辅助函数
<script>
import { mapState, mapGetters } from 'vuex'
export default {
computed: {
...mapState(['themeColor']),
...mapGetters(['isLoggedIn'])
}
}
</script>
避免过度渲染
// 使用 Object.assign 创建新引用
mutations: {
UPDATE_ITEM(state, payload) {
state.items = Object.assign({}, state.items, payload)
}
}
五、实战案例:全局主题切换
5.1 Store 定义
// store/modules/settings.js
export default {
namespaced: true,
state: () => ({
theme: 'light',
colors: {
light: { primary: '#42b983' },
dark: { primary: '#34495e' }
}
}),
mutations: {
TOGGLE_THEME(state) {
state.theme = state.theme === 'light' ? 'dark' : 'light'
}
}
}
5.2 组件中使用
<template>
<view :style="{ backgroundColor: themeColor }">
<button @click="toggleTheme">切换主题</button>
</view>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
...mapState('settings', ['theme', 'colors']),
themeColor() {
return this.colors[this.theme].primary
}
},
methods: {
...mapMutations('settings', ['TOGGLE_THEME']),
toggleTheme() {
this.TOGGLE_THEME()
}
}
}
</script>
总结
通过 Vuex 在 UniApp 中实现状态管理,开发者可以:
- 集中管理跨组件共享数据
- 通过严格的修改流程保证数据可追溯
- 实现高效的模块化开发
- 结合 UniApp 特性处理多端存储