You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vuex模块的mutation中获取原始值而非Observer类型对象

问题根因

  • Vue 2 会自动对所有存入Vuex的state对象做响应式代理,包装为你看到的Observer类型,属于框架正常行为。该类型对象支持普通对象的所有遍历操作(Object.keys()、for...in等),无需特意转换为普通对象即可读取属性。
  • 你测试的JSON.parse(JSON.stringify())和cloneDeep返回空对象,本质是调用方法时this.users尚未完成赋值,初始值就是空对象{},不是转换方法失效。

可行解决方案

方案1:使用官方API直接取原始值

如果你使用的是Vue 2.7+ 版本,或者项目中引入了@vue/composition-api,直接调用toRaw方法即可获取未被代理的原始对象:

import { toRaw } from 'vue' // Vue 2.7+ 直接从vue包导入,低版本从@vue/composition-api导入

@Mutation
public setUsers(usersList: string[]) {
  const rawUsers = toRaw(this.users)
  // rawUsers 就是完全没有响应式代理的普通对象
  this.users = GlobalUtils.mapIdsToItems(usersList, rawUsers)[0];
}

方案2:缓存原始值规避响应式代理

如果你的项目不支持toRaw方法,可以单独声明变量缓存原始值,完全绕开响应式代理读取:

// 模块外部声明原始值缓存,不会被Vue做响应式代理
let rawUsers: ArrayToObjMap<Users> = {};

@Module({
    namespaced: true,
    name: 'myModule',
    dynamic: true,
    store
})
export class MyModule extends VuexModule {
    public users: ArrayToObjMap<Users> = rawUsers;

    @Action
    public async initialize() {
      const fetchedUsers = await UsersService.getUsers();
      this.context.commit('setUsers', fetchedUsers);
    }

    @Mutation
    public setUsers(usersList: string[]) {
      // 直接操作非响应式的原始值做计算
      rawUsers = GlobalUtils.mapIdsToItems(usersList, rawUsers)[0];
      this.users = rawUsers;
    }
}

方案3:直接遍历响应式对象

如果没有特殊需求,不需要特意转成普通对象,直接遍历Observer对象即可正常拿到所有属性:

@Mutation
public setUsers(usersList: string[]) {
  this.users = GlobalUtils.mapIdsToItems(usersList, this.users)[0];
  // 直接遍历即可,无需转换
  Object.keys(this.users).forEach(userId => {
    console.log(userId, this.users[userId])
  })
}

内容的提问来源于stack exchange,提问作者D.Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 18:06:03