前端核心框架vue之(vuex状态篇4/5)
写在前面的话:在学习一个新知识前,主包提醒大家需要思考为什么会出现这么一个东西,主包在学习vue和传统js已经和兄弟们讨论了这个问题;vue就是因为传统的DOM操作太过繁琐,才会诞生出响应式框架,vue会自动帮你进行dom操作;我们只需要更加关注逻辑本身。所以现在思考为什么会用到状态管理???
一、什么是 Vuex?【超白话解释】
想象你在做一个多人游戏,游戏里有很多组件(角色、界面、状态栏等等),每个组件可能都需要用到同一份数据,比如:玩家的得分、生命值、游戏状态。
Vuex 就是一个“大管家”,专门负责集中管理这些公共数据,而不是让每个组件都自己保管一份。
🎯 **一句话理解:**Vuex 就是 Vue 项目里用来“集中存储 + 管理 + 共享数据”的工具。
二、Vuex 核心概念【通俗版表格讲解】
名称 | 本质 | 你可以把它理解成… | 功能 |
---|---|---|---|
state | 数据仓库 | “仓库里的货” | 储存共享数据 |
getters | 派生数据计算器 | “加工厂” | 从 state 里衍生出新值 |
mutations | 同步修改指令 | “搬运工” | 只能同步修改 state |
actions | 异步操作员 | “打电话叫搬运工” | 可以异步处理后再改 state |
modules | 分区仓库 | “不同区域的仓库” | 管理大型项目中的数据 |
三、快速上手结构讲解(基于 Vue CLI 项目)
// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex) // 启用 Vuex 插件export default new Vuex.Store({state: {count: 0 // 共享数据:计数器初始为 0},mutations: {increment(state) {state.count++ // 每次调用 increment 就让 count +1}},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment') // 延迟 1 秒后执行 mutations 里的 increment}, 1000)}},getters: {doubleCount: state => state.count * 2 // 派生一个值:count 的两倍}
})
💡 这个
store/index.js
会在main.js
中被Vue.prototype.$store
注册到全局,所有组件都可以访问。
四、核心部分详解(每一项都解释给你听)
1. state
:储存数据的地方
state: {count: 0
}
📦 把它理解成一个公共的数据仓库,全项目都可以来取数据。
在组件里获取方法(建议写在 computed
里,这样会响应式):
computed: {count() {return this.$store.state.count}
}
2. mutations
:同步修改数据的方法(必须用它改)
mutations: {increment(state) {state.count++}
}
❗ Vuex 的规定是:你不能直接改 state,必须用 mutations 修改。
在组件里调用:
methods: {addOne() {this.$store.commit('increment')}
}
commit
是 Vuex 的方法,表示“提交一个 mutation”。
3. actions
:处理异步,再间接调用 mutations
actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment')}, 1000)}
}
⏰ 如果你想做“等一下再加一”,或者“从服务器拿到数据后再更新”,就需要 actions。
组件里用:
methods: {asyncAdd() {this.$store.dispatch('incrementAsync')}
}
dispatch
表示调用一个异步方法(actions)
4. getters
:从 state 派生新数据(类似 computed)
getters: {doubleCount: state => state.count * 2
}
🚀 你有时会希望展示“某个状态的结果”,比如“得分 * 2”,就可以写在 getters 里。
使用方法:
computed: {doubleCount() {return this.$store.getters.doubleCount}
}
五、Modules:拆分 store 为多个子模块
项目大了,每个模块都有自己的数据,就像:
// store/modules/user.js
export default {state: () => ({name: 'Tom'}),mutations: {setName(state, newName) {state.name = newName}},actions: {updateName({ commit }, name) {commit('setName', name)}},getters: {upperName: state => state.name.toUpperCase()}
}
然后主 store 这样引入:
// store/index.js
import user from './modules/user'export default new Vuex.Store({modules: {user}
})
用法:
this.$store.state.user.name
this.$store.dispatch('user/updateName', 'Jerry')
六、辅助函数(简化写法)
Vuex 提供了很多简写方法,方便你不用写太多 this.$store:
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'export default {computed: {...mapState(['count']),...mapGetters(['doubleCount'])},methods: {...mapMutations(['increment']),...mapActions(['incrementAsync'])}
}
等同于手动写的 computed 和 methods。
七、Vuex 数据流图(可视化理解)
组件点击按钮 ——> dispatch("action") 异步 ——> commit("mutation") 同步 ——> state 改变
组件展示数据 <—— mapState/mapGetters 获取
📌 所有数据变动都必须走一套流程,这样才能被追踪、调试。
八、何时用 Vuex?什么项目才需要?
Vuex 是给多个组件共享数据准备的。
🟢 使用场景:
- 用户登录状态(多个组件都需要)
- 商品购物车数量
- 多页切换的表单临时缓存
🔴 不推荐使用:
- 只有一个组件用到的数据(直接放 data 就行)
九、Vuex 持久化存储(数据保留到刷新后)
Vuex 的数据默认刷新页面就没了。你可以结合 localStorage
实现持久化。
watch: {'$store.state.count': function (newVal) {localStorage.setItem('count', newVal)}
}
还可以用插件 vuex-persistedstate
,自动帮你保存/恢复。
十、Vue 3 更推荐用 Pinia(vite+vue3+pinia)
如果你将来用 Vue 3 项目,可以考虑替代 Vuex 的 Pinia,语法更简单、类型更强。