技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • Vue2 基础

    • Vue 学习指南
    • Vue2 快速入门
    • Vue2 模板语法
    • Vue2 组件基础
    • Vue2 计算属性与侦听器
    • Vue2 生命周期
  • Vue2 进阶

    • Vue2 组件通信
    • Vue2 插槽详解
    • Vue2 混入与自定义指令
    • Vue2 过渡与动画
    • Vuex 状态管理
  • Vue2 高级

    • Vue2 性能优化
    • Vue2 服务端渲染(SSR)
    • Vue2 源码解析
  • Vue3 基础

    • Vue3 快速入门
    • Vue3 Composition API
    • Vue3 响应式系统
    • Vue3 组件基础
    • Vue3 生命周期
  • Vue3 进阶

    • Vue3 组合式函数
    • Vue3 组件通信
    • Vue3 Teleport 与 Suspense
    • Pinia 状态管理
    • Vue Router 4
  • Vue3 高级

    • Vue3 TypeScript
    • Vue3 性能优化
    • Vue3 测试
    • Vue3 SSR
    • Vue3 源码解析
  • 实战项目

    • Vue2 实战项目
    • Vue3 实战项目
    • Vue2 迁移 Vue3

Vuex 状态管理

核心概念

State

const store = new Vuex.Store({
  state: {
    count: 0
  }
})

// 组件中访问
this.$store.state.count

// 使用 mapState
import { mapState } from 'vuex'

computed: {
  ...mapState(['count']),
  ...mapState({
    countAlias: 'count',
    countPlusLocalState(state) {
      return state.count + this.localCount
    }
  })
}

Getters

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    },
    doneTodosCount: (state, getters) => {
      return getters.doneTodos.length
    },
    getTodoById: (state) => (id) => {
      return state.todos.find(todo => todo.id === id)
    }
  }
})

// 使用
this.$store.getters.doneTodos
this.$store.getters.getTodoById(2)

// 使用 mapGetters
import { mapGetters } from 'vuex'

computed: {
  ...mapGetters(['doneTodosCount']),
  ...mapGetters({
    doneCount: 'doneTodosCount'
  })
}

Mutations

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment(state) {
      state.count++
    },
    incrementBy(state, payload) {
      state.count += payload.amount
    }
  }
})

// 提交 mutation
this.$store.commit('increment')
this.$store.commit('incrementBy', { amount: 10 })

// 使用 mapMutations
import { mapMutations } from 'vuex'

methods: {
  ...mapMutations(['increment']),
  ...mapMutations({
    add: 'increment'
  })
}

Actions

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    increment(context) {
      context.commit('increment')
    },
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment')
      }, 1000)
    },
    async actionA({ commit }) {
      const data = await fetch('/api/data')
      commit('setData', data)
    }
  }
})

// 分发 action
this.$store.dispatch('increment')
this.$store.dispatch('incrementAsync')

// 使用 mapActions
import { mapActions } from 'vuex'

methods: {
  ...mapActions(['increment']),
  ...mapActions({
    add: 'increment'
  })
}

Modules

const moduleA = {
  namespaced: true,
  state: () => ({ count: 0 }),
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    incrementIfOdd({ state, commit }) {
      if (state.count % 2 === 1) {
        commit('increment')
      }
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2
    }
  }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA
  }
})

// 访问模块
this.$store.state.a.count
this.$store.getters['a/doubleCount']
this.$store.commit('a/increment')
this.$store.dispatch('a/incrementIfOdd')

项目结构

store/
├── index.js          # 组装模块并导出 store
├── actions.js        # 根级别的 action
├── mutations.js      # 根级别的 mutation
└── modules/
    ├── user.js       # 用户模块
    └── cart.js       # 购物车模块

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import cart from './modules/cart'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    user,
    cart
  }
})

store/modules/user.js

export default {
  namespaced: true,
  state: {
    userInfo: null
  },
  mutations: {
    SET_USER_INFO(state, userInfo) {
      state.userInfo = userInfo
    }
  },
  actions: {
    async getUserInfo({ commit }) {
      const res = await fetch('/api/user')
      commit('SET_USER_INFO', res.data)
    }
  },
  getters: {
    userName: state => state.userInfo?.name
  }
}
最近更新: 2026/1/27 15:51
Contributors: hailong
Prev
Vue2 过渡与动画