大家好,我是小杨,一个在Vue世界里摸爬滚打6年的老司机。今天要和大家聊聊Vuex这个"甜蜜的负担"——刚入门时觉得它像丈母娘的要求又多又烦,用顺手后发现简直是开发大型项目的救命稻草!
(温馨提示:本文附带咖啡店点单系统完整代码示例,文末自取~)
一、🌰 举个栗子:没有Vuex的日子有多苦?
去年我接了个咖啡店点餐系统的项目,刚开始想着:"不就几个页面传数据嘛,用props和event足够了!"
结果代码写成这样:
// 父组件
<ChildA :order="order" @update="handleUpdate"/>
<ChildB :order="order" @update="handleUpdate"/>
<ChildC :order="order"/>
// 子组件
this.$emit('update', newOrder)
三天后:
- 页面层级深到需要props穿越5层组件
- 兄弟组件通信要靠共同的祖爷爷组件中转
- 改个需求要翻遍十几个文件
我意识到——是时候请出Vuex这个救兵了!
二、🚀 Vuex四件套:咖啡店的中央管理系统
想象Vuex就是咖啡店的中央控制台:
1. State - 咖啡店库存表
state: {
coffeeBeans: 100, // 咖啡豆库存
milk: 50, // 牛奶库存
currentOrder: null // 当前订单
}
2. Mutations - 唯一能改库存的人(店长)
mutations: {
SET_ORDER(state, payload) {
state.currentOrder = payload
},
USE_INGREDIENTS(state, {beans, milk}) {
state.coffeeBeans -= beans
state.milk -= milk
}
}
3. Actions - 咖啡师的工作流程
actions: {
async makeCoffee({ commit, state }, order) {
if (state.coffeeBeans < 10) {
我.alert('咖啡豆不足!')
return
}
await 我.煮咖啡() // 模拟异步操作
commit('USE_INGREDIENTS', { beans: 10, milk: 5 })
commit('SET_ORDER', order)
}
}
4. Getters - 今日特饮推荐
getters: {
recommend: state => {
return state.coffeeBeans > 50
? '推荐手冲咖啡'
: '今日特价:美式咖啡'
}
}
三、💻 在项目中如何食用?
1. 安装并注入Store
// store/index.js
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
// main.js
import store from './store'
new Vue({ store }).$mount('#app')
2. 组件中使用(三种姿势)
姿势一:直接调用(适合紧急情况)
this.$store.dispatch('makeCoffee', '拿铁')
const recommend = this.$store.getters.recommend
姿势二:map辅助函数(优雅永不过时)
import { mapActions, mapGetters } from 'vuex'
export default {
methods: {
...mapActions(['makeCoffee'])
},
computed: {
...mapGetters(['recommend'])
}
}
姿势三:Composition API(Vue3真香)
import { useStore } from 'vuex'
setup() {
const store = useStore()
const recommend = computed(() => store.getters.recommend)
const orderCoffee = () => {
store.dispatch('makeCoffee', '澳白')
}
}
四、🚨 血泪教训:我踩过的那些坑
-
Mutation必须同步!
有次我在mutation里调接口,导致devtools无法追踪状态变化... -
Module的命名空间
忘记加namespaced: true,导致action重名冲突:// 错误示范 this.$store.dispatch('updateOrder') // 调用的是哪个模块的? // 正确姿势 this.$store.dispatch('order/updateOrder') -
Store太大怎么办?
用模块化拆分,就像咖啡店分前厅和后厨:modules: { order: orderModule, // 订单相关 menu: menuModule, // 菜单管理 user: userModule // 用户信息 }
五、🌟 小杨的私藏最佳实践
-
目录结构这样排
store/ ├── index.js # 组装模块 ├── actions.js # 根级action ├── modules/ │ ├── cart.js # 购物车模块 │ └── user.js # 用户模块 -
配合LocalStorage持久化
// 用户登录后保存状态 localStorage.setItem('user', JSON.stringify(state.user)) // 初始化时读取 state.user = JSON.parse(localStorage.getItem('user')) || {} -
Vuex+TypeScript的正确姿势
interface CoffeeState { beans: number milk: number } const state: CoffeeState = { beans: 100, milk: 50 }
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.
✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!