Vuex 简介

Vuex 是专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

什么是状态管理

在 Vue 应用中,组件之间需要共享数据:

  • 父子组件通过 props 和 events 通信
  • 兄弟组件需要通过父组件中转
  • 跨层级组件通信更加复杂

当应用变得复杂时,这种分散的状态管理方式变得难以维护。Vuex 提供了一个统一的状态管理中心,解决了这些问题。

核心概念

Vuex 包含以下核心概念:

State

单一状态树,存储应用的所有状态:

const store = new Vuex.Store({
  state: {
    count: 0,
    user: null,
    todos: []
  }
})

Getter

类似计算属性,对 state 进行派生:

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

Mutation

同步更改状态:

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

Action

异步操作,提交 mutation:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment')
      }, 1000)
    }
  }
})

Module

模块化组织代码:

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

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

基本使用

安装

npm install vuex --save

创建 Store

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  }
})

export default store

在 Vue 中使用

import Vue from 'vue'
import App from './App.vue'
import store from './store'

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

在组件中访问

export default {
  computed: {
    count() {
      return this.$store.state.count
    }
  },
  methods: {
    increment() {
      this.$store.commit('increment')
    }
  }
}

数据流

Vuex 使用单向数据流:

View -> Action -> Mutation -> State -> View
  1. View:用户在界面上触发操作
  2. Action:处理异步逻辑,提交 Mutation
  3. Mutation:修改 State
  4. State:状态变化触发 View 更新

为什么使用 Vuex

适用场景

  • 多个组件共享状态
  • 需要在组件间传递数据
  • 需要全局状态管理
  • 需要记录状态变化历史

不适用场景

  • 小型简单应用
  • 组件间通信简单
  • 不需要共享状态

与其他方案对比

事件总线

// 事件总线
const bus = new Vue()

// 发送事件
bus.$emit('event-name', data)

// 接收事件
bus.$on('event-name', data => {
  // 处理数据
})

缺点:

  • 数据分散,难以追踪
  • 没有时间旅行调试
  • 代码难以维护

Vuex

// 发送
this.$store.dispatch('actionName', data)

// 接收
computed: {
  data() {
    return this.$store.state.data
  }
}

优点:

  • 集中管理状态
  • 可预测的状态变化
  • 支持 DevTools 调试
  • 代码结构清晰

项目结构

推荐的项目结构:

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

严格模式

在严格模式下,任何 Mutation 外的状态修改都会抛出错误:

const store = new Vuex.Store({
  strict: process.env.NODE_ENV !== 'production'
})

不要在发布环境下启用严格模式,以避免性能损失。

表单处理

双向绑定状态

export default {
  computed: {
    message: {
      get() {
        return this.$store.state.message
      },
      set(value) {
        this.$store.commit('setMessage', value)
      }
    }
  }
}

使用 v-model

<input v-model="message">

小结

Vuex 核心要点:

  1. 单一状态树:所有状态集中在一个对象中
  2. 单向数据流:View -> Action -> Mutation -> State
  3. 核心概念:State、Getter、Mutation、Action、Module
  4. 适用场景:中大型应用的状态管理
  5. 开发工具:Vue DevTools 支持