10、Vue3中Vuex从入门到实战:手写迷你Vuex,掌握前端状态管理核心

Vue3中Vuex从入门到实战:手写迷你Vuex,掌握前端状态管理核心

在Vue3项目开发中,组件化让代码复用和维护更高效,但跨组件、跨页面的数据共享却成了高频痛点——用户登录信息、全局权限、公共计数器等数据,如果靠组件传参层层传递,代码会变得混乱不堪。这时候,Vuex就成了前端状态管理的“大管家”,帮我们集中式管理共享数据。本文将从前端数据管理的痛点出发,带你吃透Vuex的核心用法,甚至手写一个迷你Vuex理解其底层原理。

一、前端数据管理:为什么需要Vuex?

现代Web应用由组件、数据、路由三大核心构成,组件内部的私有数据用ref/reactive管理即可,但共享数据的管理却需要更规范的方式。

我们先试想一个简单场景:用全局变量存储共享数据。

window._store ={}// 全局存储数据

这种方式看似简单,但存在致命问题:window._store不是响应式的,修改数据后Vue组件无法自动更新视图。如果我们用Vue的响应式API包裹全局数据,并提供统一的修改方法,这就是Vuex的雏形——本质是“响应式的全局数据 + 规范化的修改规则”

二、Vuex是什么?

Vuex是Vue官方的状态管理库,核心作用是集中式存储和管理应用中所有组件的共享状态

可以做一个形象的类比:

  • 小型项目(初创公司):组件私有数据(个人办公用品)随便用,无需规范;
  • 中大型项目(成熟公司):共享数据(公共办公用品)需要“管家”统一管理,申请、修改都有规范——Vuex就是这个“管家”。

核心原则:组件私有数据用ref/reactive管理,跨组件/跨页面共享数据用Vuex管理

三、Vuex快速上手:从安装到组件使用

1. 安装Vuex

Vue3需安装Vuex 4.x版本(@next标识):

npminstall vuex@next 

2. 创建Store实例

src/store/index.js中创建核心的Store,包含state(存储数据)和mutations(同步修改数据的方法):

import{ createStore }from'vuex'const store =createStore({// 定义共享数据state(){return{count:666}},// 定义修改数据的方法(唯一能修改state的地方)mutations:{add(state){ state.count++}}})exportdefault store 

3. 注册Store到Vue应用

在项目入口src/main.js中注册,让所有组件能访问Store:

import{ createApp }from'vue'import App from'./App.vue'import store from'./store'const app =createApp(App) app.use(store)// 注册Vuex app.mount('#app')

4. 组件中使用Vuex

新建src/components/Count.vue,通过useStore获取Store,用计算属性读取state,用commit触发mutation修改数据:

<template> <div @click="add">点击累加:{{ count }}</div> </template> <script setup> import { computed } from 'vue' import { useStore } from 'vuex' // 获取Store实例 const store = useStore() // 读取共享数据(计算属性保证响应式) const count = computed(() => store.state.count) // 触发mutation修改数据(不能直接修改store.state.count) function add() { store.commit('add') } </script> 

四、手写迷你Vuex:理解底层原理

Vuex的核心原理其实很简单:响应式数据 + 依赖注入 + 规范化修改规则。我们用30行代码实现一个迷你版Vuex。

1. 实现核心逻辑(src/store/gvuex.js)

import{ inject, reactive }from'vue'// 依赖注入的唯一标识constSTORE_KEY='__store__'// 供组件获取Store实例的方法exportfunctionuseStore(){returninject(STORE_KEY)}// 创建Store实例的方法exportfunctioncreateStore(options){returnnewStore(options)}classStore{constructor(options){this.$options = options // 用reactive包裹state,让数据响应式this._state =reactive({data: options.state()})// 存储mutation方法this._mutations = options.mutations }// 对外暴露state(只读)getstate(){returnthis._state.data }// 触发mutation的方法commit=(type, payload)=>{const mutation =this._mutations[type] mutation &&mutation(this.state, payload)}// 供app.use(store)调用的安装方法(依赖注入)install(app){ app.provide(STORE_KEY,this)// 全局注入Store}}

2. 替换官方Vuex使用迷你版

修改src/store/index.js,替换为手写的gvuex

// import { createStore } from 'vuex'import{ createStore }from'./gvuex'const store =createStore({state(){return{count:666}},mutations:{add(state){ state.count++}}})exportdefault store 

此时组件中使用useStorecommit的方式和官方Vuex完全一致,核心原理已复刻!

五、Vuex进阶:Getters和Actions

1. Getters:Vuex的“计算属性”

Getters用于对state做派生计算(类似组件的computed),比如实现count的双倍值:

// src/store/index.jsconst store =createStore({state(){return{count:666}},getters:{double(state){return state.count *2}},mutations:{add(state){ state.count++}}})

组件中使用:

const double =computed(()=> store.getters.double)

2. Actions:处理异步修改

Vuex规定mutation只能做同步操作,异步逻辑(如接口请求、延时)需放在actions中,再通过commit触发mutation

// src/store/index.jsconst store =createStore({// ...其他配置actions:{// 异步累加(模拟1秒后修改)asyncAdd({ commit }){setTimeout(()=>{commit('add')},1000)}}})

组件中通过dispatch触发action:

functionasyncAdd(){ store.dispatch('asyncAdd')}

六、Vuex核心设计思想:数据流向

Vuex的核心是“单向数据流”,保证数据修改可追溯:

  1. 组件通过dispatch触发action(异步)或直接commit触发mutation(同步);
  2. mutation是修改state的唯一入口,同步修改state
  3. state更新后,组件通过计算属性读取最新值,视图自动更新。

七、下一代Vuex:Pinia

Vuex对TypeScript的类型推导支持不够友好,因此Vuex作者推出了Pinia(被称为“Vuex5”):

  • 天生支持TypeScript,类型推断更友好;
  • 无需嵌套模块,API更简洁;
  • 完美兼容Vue Devtools;
  • 可作为Vuex的替代方案,学习成本低。

八、总结

  1. 核心原则:私有数据用ref/reactive,共享数据用Vuex;
  2. 核心概念
    • state:存储共享数据;
    • mutation:同步修改state(唯一入口);
    • getters:派生计算state
    • action:处理异步,内部调用mutation
  3. 底层原理:响应式数据(reactive) + 依赖注入(provide/inject) + 规范化修改规则;
  4. 进阶选型:TypeScript项目优先考虑Pinia。

思考题

你的项目中哪些数据适合放在Vuex中管理?比如:

  • 用户登录状态、用户名、权限;
  • 全局主题、布局配置;
  • 购物车数据、全局计数器;
  • 多页面共享的筛选条件、分页信息。

欢迎在评论区交流你的项目实践~


📌 本文配套代码已整理,可结合Vue3项目实操,理解更深刻。如果觉得有帮助,欢迎点赞+收藏~

Read more

双剑破天门:攻防世界Web题解之独孤九剑心法(九)

双剑破天门:攻防世界Web题解之独孤九剑心法(九)

免责声明:用户因使用公众号内容而产生的任何行为和后果,由用户自行承担责任。本公众号不承担因用户误解、不当使用等导致的法律责任 **本文以攻防世界部分题为例进行演示,后续会对攻防世界大部分的web题目进行演示,如果你感兴趣请关注** 目录 一:Supersqli 二:Warmup 三:总结 1.supersqli 2.Warmup 一:Supersqli 打开如下所示,初步筛查这应该是一道SQL注入题 这确实是一道SQL注入 1’ or 1=1 # 那接下来就是查询字段数 字段数为2 1’ order by 2 # 查询数据库 正常的查询发现不行,被过滤了 但是没有过滤分号那就可以堆叠注入联合show 1’;show tables ;# 成功查询到一个特殊的表 1';show columns from `1919810931114514`;# 查询发现此表含flag但select被过滤如何查询flag 利用handler代替select

By Ne0inhk

别再被a标签download坑了!前端文件下载重命名的终极解决方案(含后端header设置技巧)

前端文件下载重命名的实战指南:突破a标签download限制的完整方案 当用户点击下载按钮时,文件名显示乱码或保持原始名称——这是许多开发者都遇到过的痛点。传统解决方案依赖a标签的download属性,但实际开发中你会发现这个看似简单的功能隐藏着诸多兼容性和跨域陷阱。本文将带你深入理解文件下载的底层机制,并提供一套覆盖前后端的完整解决方案。 1. 为什么a标签的download属性总让你失望 几乎所有前端开发者最初接触文件下载时,都会使用这样的代码: <a href="report.pdf" download="2023年度报告.pdf">下载报告</a> 理论上这行代码应该让用户下载的文件自动重命名为"2023年度报告.pdf",但现实往往事与愿违。经过大量项目实践,我总结了download属性失效的三大典型场景: 1. 跨域限制:当文件域名与当前页面不同时(包括http/https协议差异),Chrome和Firefox会直接忽略download属性 2. 浏览器兼容性:Safari直到2020年才部分支持此属性,而某些移动端浏览器仍存在兼容问题 3. 特殊文

By Ne0inhk

Python 四大 Web 框架对比解析:FastAPI、Django、Flask 与 Tornado

目录 一、框架概述及设计目标 二、核心差异详解 三、详细应用场景与角色定位 1. Django — 企业级全栈Web开发的首选 2. Flask — 灵活、轻量的微框架 3. FastAPI — 现代、高性能异步API框架 4. Tornado — 异步网络编程与实时通信 四、总结对比与选择建议 五、框架选择示意图 结语 Python 在 Web 开发领域有众多框架,功能和定位各有不同。本文重点对比四个主流框架:FastAPI、Django、Flask、Tornado,帮你了解它们的差异、应用场景和各自擅长解决的问题。 一、框架概述及设计目标 框架设计初衷特点概览代表适用场景Django全功能、高度集成的全栈框架“开箱即用” ,集成ORM、模板、后台管理、安全认证复杂业务系统、内容管理、企业级应用Flask轻量级微框架,灵活自由核心简单,

By Ne0inhk
前端老鸟血泪史:本地存储爆雷怎么办?5招搞定缓存顽疾还能让页面秒开

前端老鸟血泪史:本地存储爆雷怎么办?5招搞定缓存顽疾还能让页面秒开

前端老鸟血泪史:本地存储爆雷怎么办?5招搞定缓存顽疾还能让页面秒开 * 前端老鸟血泪史:本地存储爆雷怎么办?5招搞定缓存顽疾还能让页面秒开 * 别整那些虚的,聊聊咱们天天都要面对的"存数据"这点破事 * 扒一扒浏览器给咱们留的那些"储物柜"底细 * 深究那些让你又爱又恨的存储黑科技 * 这几种方案各有各的坑,踩平了才是真本事 * 真实项目里大家都是怎么"缝缝补补"过日子的 * 遇到诡异的缓存问题别慌,按这个路子查准没错 * 几个让代码更健壮、性能更起飞的老司机经验 * 要是看完你还觉得缓存简单,那一定是你遇到的坑还不够多 前端老鸟血泪史:本地存储爆雷怎么办?5招搞定缓存顽疾还能让页面秒开 说实话,写这篇文章之前我抽了三根烟。不是因为别的,就是想起这些年被本地存储坑过的那些夜晚,血压有点上来了。你们懂那种感受吗?凌晨两点,用户群里突然炸锅,说数据丢了、页面白了、刷新一下东西全没了。你一边陪着笑说"马上修复",一边疯狂翻代码,

By Ne0inhk