Vue 组件中获取 Vuex state 数据的三种核心方式

这段代码展示了 Vue 组件中获取 Vuex state 数据的三种核心方式,核心差异在于「响应式表现」「数据更新机制」「适用场景」,

下面逐一拆解每种方式的原理、特点和为什么会有这些区别:

html 复制代码
<template>
  <div class="about">
    <h2>直接取的</h2>
    <!--方式1: 直接取-->
    <p>取出Vuex的数据,user: {{this.$store.state.user}}</p>
    <p>取出Vuex的数据,token: {{this.$store.state.token}}</p>
    <hr>
    <h2>data中获取的</h2>
    <!--方式2: 在data中获取-->
    <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>
<script>
export default {
  name: 'AboutView',
  data() {
    return {
      // 可以在data中直接获取Vuex中的数据
      user: this.$store.state.user,
      // token: this.$store.state.token,
      newToken:''
    }
  },
  // 建议使用计算属性取出Vuex的数据,而不是data
  computed:{
    token2(){
      return this.$store.state.token
    }
  }
  ,
  methods: {
    changeToken(){
      // 调用mutations中的方法,修改token
      // this.$store.commit("mutations中定义的方法名", "调用时传递的参数")
      this.$store.commit("setToken", this.newToken)
    }
  }
}
</script>

一、方式 1:模板中直接取 this.$store.state.xxx

写法 html

javascript 复制代码
<p>取出Vuex的数据,user: {{this.$store.state.user}}</p>
核心原理

模板渲染时实时访问 Vuex 的 state 对象属性 ------Vuex 的 state 本身是响应式的,模板每次渲染 / 更新都会重新读取 $store.state.xxx 的最新值。

关键特点
  1. 完全响应式 :当 state 中的 user/token 被修改(比如通过 mutation),模板会立刻同步更新;
  2. 无缓存 :每次模板重渲染都会重新读取 state(性能影响可忽略,除非高频渲染);
  3. 语法简单但冗余 :直接写 this.$store.state.xxx 直观,但多次使用会导致模板代码臃肿,维护性差。
适用场景
  • 临时调试、快速验证数据;
  • 只在模板中少量使用 state 数据的简单场景。
为什么能实时更新?

Vuex 的 state 是基于 Vue 的响应式对象实现的,模板中访问 $store.state.xxx 会触发 Vue 的「依赖收集」,当 state 数据变化时,Vue 会通知模板重新渲染。

二、方式 2:在 data 中获取 this.$store.state.xxx

写法 js

javascript 复制代码
data() {
  return {
    user: this.$store.state.user, // 初始化时赋值
    newToken:''
  }
}
核心原理

data 中的属性在组件实例化时(beforeCreate/created 阶段)只赋值一次 ------ 把当时 $store.state.user 的「初始值」拷贝给 data.user,后续 state 变化不会同步到 data.user

关键特点
  1. 非响应式 :这是最核心的问题!比如通过 changeToken 修改了 state.token,但 data 中如果定义了 token: this.$store.state.token,模板里的 {``{token}} 永远是初始化的旧值,不会更新;
  2. 数据是 "拷贝"data.user 只是拿到了 state.user 初始化时的取值(如果是基本类型,是值拷贝;如果是引用类型,是地址拷贝,但 state 本身的响应式不会传递给 data 的属性);
  3. 模板写法简洁 :模板中只需写 {``{user}},无需写冗长的 $store.state
为什么不推荐?

data 的设计初衷是存储「组件自身的局部状态」,其初始化逻辑只执行一次,无法感知 Vuex state 的后续变化 ------ 这会导致 "数据不一致" 的 bug(比如 state 改了,但组件显示的还是旧值)。

适用场景

几乎不推荐使用 ,除非能 100% 确定 state 中的该数据在组件生命周期内永远不会变化(比如静态常量)。

三、方式 3:在 computed(计算属性)中获取 this.$store.state.xxx

重要用法: 一般从state中取出的数据要放在computed中而不是data中!

写法 js

javascript 复制代码
computed:{
  token2(){
    return this.$store.state.token
  }
}
核心原理

计算属性会「依赖收集」------ 它会监听 this.$store.state.token 的变化,当 state.token 被修改时,计算属性会自动重新计算返回最新值,并触发模板更新。同时,计算属性有「缓存特性」:只要依赖的 state.token 不变,多次访问 token2 只会执行一次计算。

关键特点
  1. 完全响应式state.token 变化,token2 会同步更新,模板也会跟着更;
  2. 有缓存 :提升性能(比如多次在模板中用 {``{token2}},不会重复读取 state);
  3. 模板简洁 + 可维护 :模板写 {``{token2}} 即可,且计算属性可以集中管理 state 数据的读取逻辑(比如后续需要对 token 做格式化,只需改计算属性,无需改所有模板);
  4. 支持扩展 :可以在计算属性中对 state 数据做派生 / 格式化(比如 return this.$store.state.token || '默认值')。
为什么是最佳实践?

计算属性完美结合了「响应式」和「简洁性」,既解决了直接取值的模板冗余问题,又避免了 data 取值的非响应式坑,同时还能通过缓存优化性能。

三种方式核心对比表

方式 响应式 缓存 模板简洁度 维护性 推荐度
模板直接取 $store.state ✅ 是 ❌ 无 ❌ 冗余 ⭐⭐
data 中赋值 ❌ 否 ❌ 无 ✅ 简洁 极差
computed 中取值 ✅ 是 ✅ 有 ✅ 简洁 ⭐⭐⭐

补充:修改 state 的逻辑(changeToken 方法)

代码中 changeToken 调用 this.$store.commit("setToken", this.newToken) 是 Vuex 规定的唯一合法修改 state 的方式(通过 mutation),这和 "取值方式" 的呼应:

  • 不管用哪种方式取值,只要通过 mutation 修改了 state.token
    • 方式 1、方式 3 会实时更新;
    • 方式 2 永远不会更新(因为是初始化一次的拷贝)。

总结

  • 临时调试用「模板直接取」;
  • 绝对不要用「data 中取值」(除非数据永不改);
  • 正式开发优先用「计算属性取值」(响应式、高性能、易维护);
  • 进阶优化:还可以用 Vuex 提供的 mapState 辅助函数简化计算属性写法(比如 ...mapState(['user', 'token'])),进一步减少代码冗余。
相关推荐
梦6501 天前
Vue 组件 vs React 组件深度对比
javascript·vue.js·react.js
2501_946230981 天前
Cordova&OpenHarmony提醒管理系统实现
android·javascript
C_心欲无痕1 天前
vue3 - useId生成唯一标识符
前端·javascript·vue.js·vue3
KoalaShane1 天前
El-slider 增加鼠标滚动滑块事件
开发语言·前端·javascript
栀秋6661 天前
Tailwind CSS:用“类名编程”重构你的前端开发体验
前端·css
C_心欲无痕1 天前
vue3 - watchSyncEffect同步执行的响应式副作用
开发语言·前端·javascript·vue.js·vue3
用泥种荷花1 天前
【前端学习AI】FewShotPromptTemplate
前端
小魔女千千鱼1 天前
在 Vue 中,this 的行为在箭头函数和普通函数中是不同的
前端·javascript·vue.js
Rysxt_1 天前
UniApp uni_modules 文件夹详细教程
开发语言·javascript·ecmascript
霍理迪1 天前
CSS盒模型布局规则
前端·javascript·css