如何在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
相关产品推荐
相关产品推荐

