模块局部状态 #

模块内部状态 #

State #

模块内的 state 是局部的,通过 state 参数访问:

javascript
const moduleA = {
  state: () => ({
    count: 0
  }),
  
  mutations: {
    INCREMENT(state) {
      // state 是模块的局部状态
      state.count++
    }
  },
  
  getters: {
    doubleCount(state) {
      // state 是模块的局部状态
      return state.count * 2
    }
  }
}

访问根状态 #

在模块内访问根状态,使用 rootState 参数:

javascript
const moduleA = {
  state: () => ({
    localCount: 0
  }),
  
  getters: {
    // 第三个参数是 rootState
    sumWithRootCount(state, getters, rootState) {
      return state.localCount + rootState.count
    },
    
    // 第四个参数是 rootGetters
    combinedGetter(state, getters, rootState, rootGetters) {
      return {
        local: state.localCount,
        root: rootState.count,
        rootDouble: rootGetters.doubleCount
      }
    }
  }
}

Mutation 中的状态 #

Mutation 只接收 state 参数(模块局部状态):

javascript
const moduleA = {
  state: () => ({
    items: []
  }),
  
  mutations: {
    ADD_ITEM(state, item) {
      // state 是模块局部状态
      state.items.push(item)
    },
    
    CLEAR_ITEMS(state) {
      state.items = []
    }
  }
}

Action 中的状态 #

Action 的 context 对象包含多种状态:

javascript
const moduleA = {
  state: () => ({
    localData: null
  }),
  
  actions: {
    async fetchData({ 
      state,      // 模块局部状态
      rootState,  // 根状态
      commit,     // 提交 mutation
      dispatch,   // 分发 action
      getters,    // 模块局部 getters
      rootGetters // 根 getters
    }) {
      // 访问局部状态
      console.log(state.localData)
      
      // 访问根状态
      console.log(rootState.user)
      
      // 访问根 getter
      console.log(rootGetters['user/isLoggedIn'])
      
      // 提交 mutation
      commit('SET_DATA', data)
      
      // 分发 action
      dispatch('otherAction')
    }
  }
}

解构使用 #

javascript
actions: {
  async fetchUserPosts({ state, rootState, commit, rootGetters }, userId) {
    // 使用局部状态
    const localCache = state.cache[userId]
    if (localCache) return localCache
    
    // 使用根状态
    const isLoggedIn = rootState.user.isLoggedIn
    if (!isLoggedIn) throw new Error('Not logged in')
    
    // 使用根 getter
    const token = rootGetters['user/token']
    
    // 获取数据
    const posts = await api.fetchUserPosts(userId, token)
    
    // 提交 mutation
    commit('SET_POSTS', { userId, posts })
    
    return posts
  }
}

Getter 中的状态 #

Getter 可以访问四种状态:

javascript
const moduleA = {
  state: () => ({
    items: []
  }),
  
  getters: {
    // 只使用局部状态
    itemCount: state => state.items.length,
    
    // 使用局部状态和局部 getter
    expensiveItems: (state, getters) => {
      return state.items.filter(item => item.price > 100)
    },
    
    // 使用根状态
    itemsWithUser: (state, getters, rootState) => {
      return state.items.map(item => ({
        ...item,
        user: rootState.users.byId[item.userId]
      }))
    },
    
    // 使用根 getter
    itemsWithDiscount: (state, getters, rootState, rootGetters) => {
      const discount = rootGetters['user/memberDiscount']
      return state.items.map(item => ({
        ...item,
        discountedPrice: item.price * discount
      }))
    }
  }
}

实战示例 #

用户模块访问根状态 #

javascript
// store/modules/user.js
export default {
  namespaced: true,
  
  state: () => ({
    profile: null,
    preferences: {}
  }),
  
  getters: {
    // 结合根状态
    userCartTotal: (state, getters, rootState) => {
      if (!state.profile) return 0
      
      const cartItems = rootState.cart.items.filter(
        item => item.userId === state.profile.id
      )
      
      return cartItems.reduce((sum, item) => sum + item.price, 0)
    }
  },
  
  actions: {
    async login({ commit, rootState, dispatch }, credentials) {
      const { user, token } = await api.login(credentials)
      
      commit('SET_PROFILE', user)
      commit('SET_TOKEN', token)
      
      // 访问根状态
      if (rootState.cart.items.length > 0) {
        // 合并购物车
        await dispatch('cart/mergeCart', null, { root: true })
      }
    }
  }
}

购物车模块访问用户状态 #

javascript
// store/modules/cart.js
export default {
  namespaced: true,
  
  state: () => ({
    items: []
  }),
  
  getters: {
    // 使用根状态获取用户折扣
    totalWithDiscount: (state, getters, rootState, rootGetters) => {
      const subtotal = state.items.reduce((sum, item) => sum + item.price, 0)
      
      // 检查用户是否登录
      if (!rootGetters['user/isLoggedIn']) {
        return subtotal
      }
      
      // 应用会员折扣
      const discount = rootGetters['user/memberDiscount']
      return subtotal * discount
    },
    
    // 使用根状态检查库存
    availableItems: (state, getters, rootState) => {
      return state.items.filter(item => {
        const product = rootState.products.byId[item.productId]
        return product && product.stock >= item.quantity
      })
    }
  },
  
  actions: {
    async checkout({ state, rootState, commit, dispatch }) {
      // 检查登录状态
      if (!rootState.user.profile) {
        throw new Error('Please login first')
      }
      
      // 创建订单
      const order = await api.createOrder({
        userId: rootState.user.profile.id,
        items: state.items
      })
      
      // 清空购物车
      commit('CLEAR_CART')
      
      // 刷新订单列表
      await dispatch('orders/fetchOrders', null, { root: true })
      
      return order
    }
  }
}

产品模块与其他模块交互 #

javascript
// store/modules/products.js
export default {
  namespaced: true,
  
  state: () => ({
    items: [],
    categories: []
  }),
  
  getters: {
    // 产品与用户收藏关联
    productsWithFavorite: (state, getters, rootState) => {
      const favorites = rootState.user.favorites || []
      
      return state.items.map(product => ({
        ...product,
        isFavorite: favorites.includes(product.id)
      }))
    },
    
    // 产品与购物车关联
    productsWithCartInfo: (state, getters, rootState) => {
      return state.items.map(product => {
        const cartItem = rootState.cart.items.find(
          item => item.productId === product.id
        )
        
        return {
          ...product,
          inCart: !!cartItem,
          cartQuantity: cartItem?.quantity || 0
        }
      })
    }
  },
  
  actions: {
    async addToCart({ rootState, dispatch }, { productId, quantity }) {
      // 检查库存
      const product = rootState.products.items.find(p => p.id === productId)
      if (product.stock < quantity) {
        throw new Error('Insufficient stock')
      }
      
      // 添加到购物车
      await dispatch('cart/addItem', { productId, quantity }, { root: true })
    }
  }
}

跨模块通信模式 #

通过 Action 通信 #

javascript
// 模块 A
actions: {
  async doSomething({ dispatch }) {
    // 调用模块 B 的 action
    await dispatch('moduleB/someAction', payload, { root: true })
  }
}

通过 Getter 组合 #

javascript
// 根 getter 组合多个模块
getters: {
  dashboardData: (state, getters) => {
    return {
      user: getters['user/profile'],
      cartCount: getters['cart/itemCount'],
      notifications: getters['notifications/unreadCount']
    }
  }
}

通过根状态共享 #

javascript
// 根状态作为共享数据
state: {
  currentUserId: null
}

// 各模块访问
getters: {
  currentUser: (state, getters, rootState) => {
    return state.users.find(u => u.id === rootState.currentUserId)
  }
}

总结 #

模块局部状态访问方式:

位置 参数 说明
Mutation state 模块局部状态
Action state 模块局部状态
Action rootState 根状态
Getter state 模块局部状态
Getter getters 模块局部 getter
Getter rootState 根状态
Getter rootGetters 根 getter

继续学习 命名空间,了解模块命名空间的使用。

最后更新:2026-03-28