Vuex Store 的核心属性及其作用详解

Vuex 的 Store 是 Vue.js 应用程序中的状态管理中心,它包含几个关键属性,每个属性都有特定的职责。下面我将详细介绍这些属性及其作用。

一、Vuex Store 的核心属性

1. state

作用:存储应用程序的状态数据(即变量数据)

特点

  • 是 Store 的数据源,类似组件的 data
  • 必须是纯对象或返回对象的函数(避免共享状态导致的污染)
  • 状态是响应式的,变更会被自动更新到依赖它的组件

示例

state: {
    
    
  count: 0,
  user: null,
  todos: []
}

组件中访问

this.$store.state.count

2. getters

作用:从 state 中派生出计算状态(类似组件的计算属性)

特点

  • 可以对 state 进行加工处理后再暴露给组件
  • 具有缓存机制,只有依赖的状态变化才会重新计算
  • 可以接收其他 getter 作为第二个参数

示例

getters: {
    
    
  doubleCount: state => state.count * 2,
  completedTodos: state => state.todos.filter(todo => todo.completed),
  remainingTodos: (state, getters) => state.todos.length - getters.completedTodos.length
}

组件中访问

扫描二维码关注公众号,回复: 17574554 查看本文章
this.$store.getters.doubleCount

3. mutations

作用:修改 state 的唯一途径(同步操作)

特点

  • 必须是同步函数
  • 每个 mutation 都有一个字符串类型的事件类型 (type) 和一个回调函数 (handler)
  • 通过 commit 方法触发
  • 建议使用常量作为 mutation 类型名(利于维护)

示例

mutations: {
    
    
  INCREMENT(state) {
    
    
    state.count++
  },
  SET_USER(state, user) {
    
    
    state.user = user
  }
}

组件中触发

this.$store.commit('INCREMENT')
this.$store.commit('SET_USER', {
    
     name: 'John' })

4. actions

作用:处理异步操作和业务逻辑,最终提交 mutation 来修改 state

特点

  • 可以包含任意异步操作
  • 通过 dispatch 方法触发
  • 第一个参数是 context 对象(包含 commit、state、getters 等)
  • 通常返回 Promise 以便于处理异步结果

示例

actions: {
    
    
  async login({
     
      commit }, credentials) {
    
    
    const user = await api.login(credentials)
    commit('SET_USER', user)
    return user
  },
  incrementAsync({
     
      commit }) {
    
    
    setTimeout(() => {
    
    
      commit('INCREMENT')
    }, 1000)
  }
}

组件中触发

this.$store.dispatch('login', {
    
     username, password })
  .then(user => {
    
     /* 处理成功 */ })
  .catch(error => {
    
     /* 处理错误 */ })

5. modules

作用:将 store 分割成模块,每个模块拥有自己的 state、getters、mutations、actions

特点

  • 适用于大型应用的状态管理
  • 可以嵌套子模块
  • 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的
  • 可以通过 namespaced: true 使其成为带命名空间的模块

示例

const userModule = {
    
    
  namespaced: true,
  state: () => ({
    
     user: null }),
  mutations: {
    
    
    SET_USER(state, user) {
    
    
      state.user = user
    }
  }
}

const store = new Vuex.Store({
    
    
  modules: {
    
    
    user: userModule
  }
})

组件中访问命名空间模块

this.$store.state.user.user  // 访问状态
this.$store.commit('user/SET_USER', user)  // 提交 mutation
this.$store.dispatch('user/login')  // 分发 action

二、辅助属性与方法

除了上述核心属性外,Vuex Store 还提供了一些有用的辅助属性和方法:

1. strict

作用:是否启用严格模式

特点

  • 在严格模式下,任何不是由 mutation 引起的状态变更都会抛出错误
  • 开发时有助于检测不规范的修改
  • 生产环境应关闭以避免性能损耗

设置方式

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

2. plugins

作用:注册插件,在 store 的生命周期中注入逻辑

常见用途

  • 持久化状态
  • 日志记录
  • 状态快照

示例

const myPlugin = store => {
    
    
  store.subscribe((mutation, state) => {
    
    
    console.log(mutation.type, mutation.payload)
  })
}

const store = new Vuex.Store({
    
    
  plugins: [myPlugin]
})

3. subscribe

作用:订阅 store 的 mutation(常用于插件开发)

特点

  • 每次提交 mutation 后调用
  • 接收一个回调函数,参数为 mutation 和 mutation 后的 state

示例

store.subscribe((mutation, state) => {
    
    
  console.log(mutation.type, mutation.payload)
})

三、属性关系图

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Actions   │ ──> │  Mutations  │ ──> │    State    │
└─────────────┘     └─────────────┘     └─────────────┘
       ▲                                      │
       │                                      ▼
       └───────────────────────────┐     ┌─────────────┐
                                   │     │  Getters    │
                                   └─────┴─────────────┘
  • 单向数据流:组件 -> Actions -> Mutations -> State -> 组件
  • Actions:处理异步和复杂逻辑
  • Mutations:唯一能改变 State 的地方(同步)
  • Getters:从 State 派生计算状态

四、最佳实践建议

  1. State 设计原则

    • 尽量扁平化,避免过度嵌套
    • 提前规划好状态结构
    • 敏感数据不应存储在 state 中
  2. Mutation 规范

    • 使用常量作为 mutation 类型
    • 一个 mutation 只做一件事
    • 保持同步,不要包含异步操作
  3. Action 使用建议

    • 处理所有异步逻辑
    • 可以组合多个 mutation
    • 返回 Promise 以便链式调用
  4. Getter 优化

    • 复杂计算放在 getter 中
    • 避免在 getter 中修改 state
    • 频繁使用的计算属性应考虑缓存

五、完整示例

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

Vue.use(Vuex)

// 定义 mutation 类型常量
const INCREMENT = 'INCREMENT'
const SET_USER = 'SET_USER'

export default new Vuex.Store({
    
    
  strict: process.env.NODE_ENV !== 'production',
  
  state: {
    
    
    count: 0,
    user: null,
    todos: [
      {
    
     id: 1, text: 'Learn Vue', completed: true },
      {
    
     id: 2, text: 'Learn Vuex', completed: false }
    ]
  },
  
  getters: {
    
    
    completedTodos: state => {
    
    
      return state.todos.filter(todo => todo.completed)
    },
    progress: (state, getters) => {
    
    
      return Math.round((getters.completedTodos.length / state.todos.length) * 100)
    }
  },
  
  mutations: {
    
    
    [INCREMENT](state) {
    
    
      state.count++
    },
    [SET_USER](state, user) {
    
    
      state.user = user
    }
  },
  
  actions: {
    
    
    incrementAsync({
     
      commit }) {
    
    
      return new Promise(resolve => {
    
    
        setTimeout(() => {
    
    
          commit(INCREMENT)
          resolve()
        }, 1000)
      })
    },
    async fetchUser({
     
      commit }, userId) {
    
    
      try {
    
    
        const user = await api.fetchUser(userId)
        commit(SET_USER, user)
        return user
      } catch (error) {
    
    
        console.error('Failed to fetch user:', error)
        throw error
      }
    }
  },
  
  modules: {
    
    
    auth: {
    
    
      namespaced: true,
      state: () => ({
    
     token: null }),
      mutations: {
    
    
        SET_TOKEN(state, token) {
    
    
          state.token = token
        }
      }
    }
  }
})

理解 Vuex Store 的这些核心属性及其相互关系,是构建可维护、可扩展的 Vue 应用程序的关键。合理使用这些属性可以帮助开发者更好地组织和管理应用状态。
在这里插入图片描述