Vuex中在action内访问状态为何需使用state.state.xxx的怪异嵌套语法
问题根因:对Vuex Action的入参结构认知偏差,不当的变量命名导致了双层state的怪异嵌套访问
核心原因解释
你在编写storeTest action时,混淆了Action和Mutation的入参规则,错误把Action的第一个入参直接当成了原生state对象,这是造成访问异常的核心原因。
Vuex中Action被dispatch触发时,传入函数的第一个参数并不是state本身,而是一个和Store实例结构对齐的上下文对象(context)。这个上下文对象内部才封装了当前模块的原生state、getters、commit方法、dispatch方法等可调用的属性和能力。
为什么会出现state.state.xxx的访问写法
你把上下文对象的形参直接命名为了state,本质是给容器起了个错误的名字:
- 这个形参实际承接的是完整的context容器,不是你定义的
fileStr、loading所在的原生state - 你通过这个形参访问
state属性时,实际是从context容器中取出了真实的原生state对象,因此写成state.state.fileStr(对应真实结构context.state.fileStr)可以正常取值 - 而你直接写
state.fileStr的时候,实际是在context容器上寻找fileStr属性,这个属性根本不存在于context的顶层,自然会取值失败
符合预期的正确写法
如果想要实现直接通过state.属性访问状态,有两种常用的正确实现方式:
- 按照入参实际结构命名,从context容器中取真实state
actions: { storeTest(context) { // 从上下文对象中提取原生state完成访问 console.log("state: ", context.state.fileStr); } } - 入参位置直接解构context中的state属性,完全匹配你原本的访问预期
actions: { // 从上下文对象中解构出state作为独立形参 storeTest({ state }) { // 这一步不需要嵌套,直接访问状态属性 console.log("state: ", state.fileStr); } }
容易混淆的规则区分:
- Mutation函数的第一个入参:直接是当前模块的原生state,不需要额外从容器中提取
- Action函数的第一个入参:是上下文容器对象,必须通过属性访问/解构才能拿到内部封装的state、commit、dispatch等内容
代码结构注意事项:你贴出的示例代码存在括号匹配错误,
actions配置结束后多写了一层嵌套大括号,运行时会触发语法解析报错,需要删除多余的闭合括号,保证Store配置的结构层级正确。
内容的提问来源于stack exchange,提问作者Fred
相关产品推荐
相关产品推荐

