Vuex state无法同步到getter且报Cannot set properties of undefined错误
问题分析
你的代码存在4个核心错误,是导致报错和数据无法正常读写的原因:
- Action 传参规则使用错误
Vuex的Action函数第一个参数是上下文对象(context),包含commit、state、dispatch等属性,你直接把第一个参数命名为state,试图直接访问state.users其实访问的是context下不存在的users属性,得到undefined,给undefined['GOOGLE_DRIVE']赋值就会抛出你遇到的报错。
正确的写法如下:
// 写法1:解构context取需要的属性 async login({ commit, state }, payload) { // 内部可直接使用commit、state } // 写法2:不解构,通过context访问对应属性 async login(context, payload) { // 访问state要写context.state,提交mutation要写context.commit }
- 缺少修改users状态的Mutation
Vuex要求所有state的修改必须通过Mutation完成,你当前只定义了重置状态的Mutation,没有写更新users的Mutation,无法合法修改状态。你注释的两种写法要么是直接改state不符合规范,要么是调用了不存在的usersMutation自然报错。
需要先补充对应的Mutation:
const mutations = { [RESET_STATE]() { Object.keys(initialState).forEach(key => { state[key] = initialState[key] }) }, // 新增更新users的Mutation SET_USER(state, { driveType, userData }) { state.users[driveType] = userData } }
然后在Action里调用这个Mutation:
// 对应上面解构context的写法 commit('SET_USER', { driveType: payload, userData: user })
- Getter 规则使用错误
Getter的固定参数只有四个:(state, getters, rootState, rootGetters),不存在你写的payload、drive参数,而且Getter是用来读取派生状态的,绝对不允许在Getter里修改state,你直接写state.users = {}相当于每次调用这个Getter都会把users清空,自然永远拿不到值。
如果要根据drive类型返回对应的用户,Getter应该写成返回函数的形式:
const getters = { getUsersByDrive: (state) => (driveType) => { return state.users[driveType] } }
调用的时候用this.$store.getters.getUsersByDrive('GOOGLE_DRIVE')就能拿到对应数据。
- 全局state定义不符合Vuex规范
你单独定义了const state = { ...initialState },如果是Vuex的store配置,应该直接把state写在配置项里,不需要单独全局声明,避免作用域混乱。
内容的提问来源于stack exchange,提问作者Jeremy Love
相关产品推荐
相关产品推荐

