在 Vue 组件中访问 Vuex 数据存在三种主要方式,它们在响应式表现、数据更新机制以及适用场景上各有不同。下面将详细解析每种方法的实现原理、特性及其差异原因。
state
一、模板中直接读取 Vuex 状态
这种方式通过在模板表达式中直接引用 this.$store.state.user 来获取全局状态:
<p>取出Vuex的数据,user: {{this.$store.state.user}}</p>
核心机制
每次模板渲染时,都会实时访问 Vuex 的 state 属性。由于 Vuex 的 state 本身是基于 Vue 响应式系统构建的,因此当 state 变化时,会触发视图的重新渲染。
主要特点- 完全响应式:一旦 state 中的数据(如 user 或 token)被 mutation 修改,界面将立即更新;
- 无缓存机制:每次重渲染都会重新读取 state,虽然对性能影响极小,但在频繁更新的组件中需注意;
- 语法直观但冗余:适合少量使用,若多处调用则导致模板代码重复、可维护性降低。
适用于临时调试或仅需简单展示 Vuex 数据的情况,尤其适合不需要复用逻辑的小型组件。
为何能实现动态更新?因为 Vuex 的 state 是响应式的对象,模板中的访问行为会被 Vue 捕获并建立依赖关系。当对应 state 字段变化时,Vue 能感知到并触发视图更新流程。
this.$store.state.xxx
二、在 data 中初始化 Vuex 数据
该方式是在组件的 data() 函数中将 Vuex 的 state 赋值给本地数据:
data() {
return {
user: this.$store.state.user,
newToken: ''
}
}
实现原理
这些数据仅在组件实例创建阶段(beforeCreate 到 created 之间)执行一次赋值操作,获取的是当前 state 的“快照”,后续即使 state 发生变化,data 中的值也不会自动同步。
关键特征- 不具备响应性:这是最大缺陷。例如通过 mutation 更新了 token,但 data 中保存的 token 仍为初始值,页面不会刷新显示新内容;
- 数据为静态拷贝:基本类型是值复制,引用类型则是引用地址复制,但原始 state 的响应式能力不会传递给 data 属性;
- 模板书写更简洁:在模板中可直接使用 {{user}},无需完整路径。
因其无法响应 Vuex state 的后续变更,容易造成界面与真实状态不一致的问题,违背了 Vue 数据驱动的设计理念。
data
三、通过计算属性获取 Vuex 数据
推荐做法是利用 computed 属性来动态读取 state:
computed: {
token2() {
return this.$store.state.token
}
}
工作原理
计算属性会在模板渲染时动态求值,并且自动追踪其依赖——即 this.$store.state.token。只要该字段发生变化,计算属性就会重新执行,从而触发视图更新。
- 具备响应式:与直接在模板中访问一样,能实时反映 state 变化;
- 支持缓存优化:只有当依赖项改变时才会重新计算,避免不必要的重复读取;
- 提升代码组织性:将复杂的状态提取逻辑封装在 computed 中,使模板和 data 更清晰。
对于需要多次使用的 Vuex 状态,应优先采用计算属性方式,既能保证响应性,又能提高性能和可维护性。
实际模板结构示例
<template>
<div class="about">
<h2>直接取的</h2>
<p>取出Vuex的数据,user: {{this.$store.state.user}}</p>
<p>取出Vuex的数据,token: {{this.$store.state.token}}</p>
<hr>
<h2>data中获取的</h2>
<p>取出Vuex的数据,user: {{user}}</p>
<p>取出Vuex的数据,token: {{token}}</p>
<hr>
<h2>调用mutations中的方法修改token</h2>
<input type="text" v-model="newToken">
<button @click="changeToken">修改token</button>
<h2>计算属性中获取的</h2>
<p>取出Vuex的数据,token: {{token2}}</p>
</div>
</template>
$store.state.xxx
state
user
token
this.$store.state.xxx
state
$store.state.xxx
data() {
return {
user: this.$store.state.user, // 初始化时赋值
newToken:''
}
}
data
$store.state.user
data.user
changeToken
state.token
data
token: this.$store.state.token
data.user
state.user
$store.state
计算属性(computed)是获取 Vuex 中状态的推荐方式。其核心机制基于依赖追踪:当所依赖的
发生变化时,计算属性会自动重新求值,并触发视图更新。同时,它具备缓存特性——只要依赖项未变,多次访问该属性不会重复执行计算逻辑。this.$store.state.xxx
这种机制确保了数据的高度响应性与良好的性能表现。例如,在模板中多次使用 {{token2}} 时,只要
没有更新,计算属性仅执行一次即可返回缓存结果,避免不必要的重复读取。state
此外,将状态提取逻辑集中于计算属性中,有助于提升代码可维护性。比如未来需要对
进行格式化处理,只需修改对应的计算属性,而无需逐一更改模板中的每一处引用。同时也支持派生数据的构建,如通过 token
实现复杂逻辑封装。return this.$store.state.token || '默认值'
computed
为什么不推荐在 data 中初始化 Vuex 状态?
的设计初衷是管理组件自身的局部状态,其初始化过程仅在组件创建时执行一次,无法监听到后续 data
的变更。这会导致界面显示的数据滞后于实际状态,产生“数据不一致”的问题(例如 state
已更新,但组件仍展示旧值)。state
尽管这种方式能让模板写法更简洁,但由于缺乏响应性,维护成本极高。因此,除非能完全确定该数据在整个组件生命周期内都不会改变(如静态常量),否则应避免使用。

为什么计算属性是最佳实践?
相比其他方式,计算属性融合了响应式更新、缓存优化和结构清晰三大优势:
- 响应式同步:一旦
更新,state.token
立即响应并刷新模板;token2 - 性能优化:利用缓存机制减少重复计算;
- 模板简洁且易于维护:模板中只需写
{{token2}},所有读取逻辑统一由计算属性管理; - 扩展性强:可在计算过程中对接口数据进行加工或格式化。
相比之下,“模板直接取值”虽然响应及时但易造成模板冗余;“data 中赋值”则完全丧失响应能力,极难维护。
三种取值方式对比表
| 方式 | 响应式 | 缓存 | 模板简洁度 | 维护性 | 推荐度 |
|---|---|---|---|---|---|
模板直接取 |
是 | 无 | 冗余 | 差 | ?? |
中赋值 |
否 | 无 | 简洁 | 极差 | ? |
中取值 |
是 | 有 | 简洁 | 优 | ??? |
关于修改 state 的规范方法(mutations)
在代码中调用 this.$store.commit("setToken", this.newToken) 是 Vuex 唯一允许修改
的合法途径。这一机制通过 mutation 确保状态变更可追踪、可调试。state
无论采用哪种取值方式,只要通过 mutation 修改了
:state.token
- 方式1(模板直接取)和方式3(计算属性)会实时更新;
- 方式2(data 赋值)则不会更新,因其只是初始快照的拷贝。
changeToken
总结建议
- 临时调试可用「模板直接取」;
- 禁止使用「data 中取值」,除非数据绝对不变;
- 正式开发一律优先选用「计算属性取值」——响应式强、性能高、易维护;
- 进阶优化可结合 Vuex 提供的辅助函数
,如mapState...mapState(['user', 'token']),进一步简化代码结构,降低冗余。
computed:{
token2(){
return this.$store.state.token
}
}
this.$store.state.token
state.token
token2
state.token
token2
state
token
return this.$store.state.token || '默认值'
changeToken

雷达卡


京公网安备 11010802022788号







