news 2026/4/8 2:29:14

Vue.js 前端开发实战之 07-Vuex 状态管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue.js 前端开发实战之 07-Vuex 状态管理

初识 Vuex

Vuex 概述

Vuex 是 Vue 官方提供的一套组件状态(即数据)管理和维护的解决方案。

Vuex 作为 Vue 的插件来使用,进一步完善了 Vue 基础代码功能,使 Vue 组件状态更加容易维护,为大型项目的开发提供了强大的技术支持。

Vuex 初体验

Vuex 3.x 文档:https://vuex.vuejs.org/zh/

Vuex 的使用:

  • 新建 HTML 文件,并使用 script 标签引入 vue.js、vuex.js。
  • 创建 Vuex 的“数据仓库” Store 对象,并初始化数据。
  • 实例化 Vue 实例,并将 Store 对象传递给 Vue 实例。
  • 在 app 盒子中,通过 this.$store.state 获取数据。

示例:Vuex 初体验

入口页面(index.html):

<div id="app"> <!-- 通过 this.$store.state.参数名 取值 --> <p>{{this.$store.state.name}}</p> </div> <script> // 创建Vuex数据仓库对象 let store = new Vuex.Store({ // state:状态即数据 state: { name: 'hello,Vuex' } }) let vm = new Vue({ el: '#app', // 挂载Vuex实例,等同于store: store store, }) </script>

示例效果:


Vuex Store 中的数据是响应式的,在组件中调用 Store 中的数据,除了可以使用 this.$store.state 外,还可以使用计算属性的方式获取数据。


示例:通过计算属性获取数据

入口页面(index.html):

<div id="app"> <!-- 通过计算属性生成参数 --> <p>{{name}}</p> </div> <script> let store = new Vuex.Store({ state: { name: 'hello,Vuex' } }) let vm = new Vue({ el: '#app', store, computed: { name() { // 在计算属性中返回store中的数据 return this.$store.state.name } } }) </script>

当一个组件需要获取多个数据时,将 store 中的数据都声明为计算属性有些麻烦,Vuex 提供了 mapState 辅助函数来生成计算属性。


示例:通过 mapState 生成计算属性

入口页面(index.html):

<div id="app"> <!-- 通过Vuex.mapState批量生成计算属性 --> <p>{{name}}</p> </div> <script> let store = new Vuex.Store({ state: { name: 'hello,Vuex' } }) let vm = new Vue({ el: '#app', store, computed: { // ...:展开运算符,将mapState的结果放到计算属性中 // ...Vuex.mapState(['name']) } }) </script>

Vuex 状态管理模式

在 Vue 中,组件的状态(数据)变化是通过 Vue 单向数据流的设计理念实现的。

在组件系统中,单向数据流是指父组件通过属性 props 传递数据到子组件,子组件不能直接修改从父组件接收的 props,而是应该通过自定义事件来通知父组件进行数据更新。

Vue 的单向数据流增强了组件之间的独立性,但是存在多个组件共享数据的时候,单向数据流就难以对数据进行维护。

Vuex 就是专门为 Vue 设计的状态(数据)管理库,利用 Vue 的细粒度数据响应机制来进行高效的状态更新。

Vuex 配置选项

mutations

在 Vuex 中,不能直接修改 store 中的数据,必须调用相应的事件处理方法处理 state 数据。

如果直接修改 store 中的数据,视图页面会发生变化,但 store 中的数据实际上并没有发生变化。


示例:直接修改 store 中的数据

入口页面(index.html):

<div id="app"> <button @click="click1">直接 count++</button> <p>{{this.$store.state.count}}</p> </div> <script> let store = new Vuex.Store({ state: { count: 0 } }) let vm = new Vue({ el: '#app', store, methods: { click1() { this.$store.state.count++ } } }) </script>

示例效果:


mutations 选项用来定义事件处理方法,用于处理 state 数据,调用 mutations 中的方法,就可以完成数据更新。


示例:使用 mutations 提交数据更新

入口页面(index.html):

<div id="app"> <button @click="click1">直接 count++</button> <button @click="click2">使用mutations修改count</button> <p>{{this.$store.state.count}}</p> </div> <script> let store = new Vuex.Store({ state: { count: 0 }, // mutations:定义数据处理方法 mutations: { // state:Vuex.Store.state对象 // param:要修改的新数据 updateCount(state, param) { // 让Store中的数据等于新的数据 state.count = param } } }) let vm = new Vue({ el: '#app', store, methods: { // ... click2() { // 通过this.$store.commit()调用mutations中的更新数据的方法 // 参数1:调用的方法名 // 参数2:新的参数的值,可以不传 this.$store.commit('updateCount', 100) } } }) </script>

示例效果:


mutations 中定义的方法是同步函数,组件数据发生变化时,触发 mutations 中的事件处理方法来更新数据,这是一种同步更新,在 mutations 中,不能有异步操作。


示例:使用 mutations 异步更新数据

入口页面(index.html):

<div id="app"> <button @click="click1">直接 count++</button> <button @click="click2">使用mutations修改count</button> <button @click="click3">3秒钟后修改count</button> <p>{{this.$store.state.count}}</p> </div> <script> let store = new Vuex.Store({ state: { count: 0 }, mutations: { updateCount(state, param) { // 定时器:三秒后修改数据(异步操作) setTimeout(function () { state.count = param }, 3000) } } }) let vm = new Vue({ el: '#app', store, methods: { // ... click3() { this.$store.commit('updateCount', 100) } } }) </script>

示例效果:


actions

actions 和 mutations 类似,都是用于定义事件处理方法的。

actions 定义的方法,可以执行异步操作,actions 的本质还是调用 mutations。


示例:使用 actions 异步更新数据

入口页面(index.html):

<div id="app"> <button @click="click1">直接 count++</button> <button @click="click2">使用mutations修改count</button> <button @click="click3">3秒钟后修改count</button> <button @click="click4">3秒钟后修改count(actions)</button> <p>{{this.$store.state.count}}</p> </div> <script> let store = new Vuex.Store({ state: { count: 0 }, // 同步方法 mutations: { updateCount(state, param) { state.count = param } }, // 异步方法 actions: { // context:即$store对象 // param:要修改的新数据 updateCount(context, param) { // 定时器:三秒后修改数据(异步操作) setTimeout(function () { // 调用$store.commit执行同步更新 // actions的本质还是mutations context.commit('updateCount', param) }, 3000) } } }) let vm = new Vue({ el: '#app', store, methods: { // ... click4() { // 通过this.$store.dispatch()调用actions中的更新数据的方法 this.$store.dispatch('updateCount', 100) } } }) </script>

示例效果:


getters

Vuex 允许在 store 中定义 getters 计算属性,类似于 Vue 实例的 computed,getters 返回值会根据它的依赖进行处理然后缓存起来,且只有当它的依赖值发生变化时才会重新计算。


示例:getters

入口页面(index.html):

<div id="app"> <p>单价:{{this.$store.state.price}}</p> <p>数量:{{this.$store.state.count}}</p> <p>总价:{{this.$store.getters.totalPrice}}</p> <p> <button @click="plus">+1</button> <button @click="minus">-1</button> </p> </div> <script> let store = new Vuex.Store({ state: { price: 10, count: 0 }, mutations: { plus(state) { state.count++ }, minus(state) { state.count-- } }, // 定义Vuex的计算属性 getters: { totalPrice(state) { return state.price * state.count } } }) let vm = new Vue({ el: '#app', store, methods: { plus() { this.$store.commit('plus') }, minus() { this.$store.commit('minus') } } }) </script>

示例效果:


modules

Vuex 提出了类似于模块化开发的方式对 store 进行管理。

modules 用于在 store 中定义模块对象。


示例:modules

入口页面(index.html):

<div id="app"> <!-- 通过 this.$store.state.模块名.xxx 调用 --> <p>{{this.$store.state.a.count}}</p> <p>{{this.$store.state.b.count}}</p> </div> <script> // 定义模块A对象 let moduleA = { state: { count: 1 } } // 定义模块B对象 let moduleB = { state: { count: 2 } } let store = new Vuex.Store({ // 定义模块 modules: { // 模块名称: 模块对象 a: moduleA, b: moduleB } }) let vm = new Vue({ el: '#app', store }) </script>

示例效果:


plugins

plugins 是 Vuex 中的插件配置选项,用于为 Vuex 添加插件。


示例:plugins

入口页面(index.html):

<div id="app"> </div> <script> // 自定义一个插件 // 插件本身是一个方法 // store:Vuex.Store对象 let myPlugin = function(store) { // subscribe方法:处理mutations // 每次mutations提交后都会执行这个方法 // mutation:调用的同步方法的信息 store.subscribe((mutation, state) => { // mutation.type:调用了什么方法 // mutation.payload:传进来什么参数 console.log("调用mutation方法:" + mutation.type + ",参数为:" + mutation.payload) }) } let store = new Vuex.Store({ // 指定插件列表 plugins: [myPlugin], mutations: { do(state) { console.log('do被执行了') } } }); store.commit('do', 'hello') let vm = new Vue({ el: '#app', store }) </script>

示例效果:


devtools

devtools 用于设置是否在 vue-devtools 中启用 Vuex 跟踪调试。


示例:devtools

入口页面(index.html):

let store = new Vuex.Store({ devtools: false, // ... })

Vuex API

模块注册

Vuex store 提供了动态创建模块的方法 store.registerModule。


示例:store.registerModule

入口页面(index.html):

let store = new Vuex.Store({}) // 参数1:模块名称 // 参数2:模块对象 store.registerModule('myModule', { state: {} })

状态替换

Vuex 提供了状态替换的方法 store.replaceState。

应尽量避免使用这个方法,在错误的位置使用这个方法会造成数据被错误覆盖。


示例:store.replaceState

入口页面(index.html):

let store = new Vuex.Store({ state: { count: 0 } }) // 参数1:要替换的新的state对象 store.replaceState({ count: 1 })

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 21:02:24

【开题答辩全过程】以 民宿预订管理系统的设计与实现为例,包含答辩的问题和答案

个人简介 一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等 开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。 感谢大家…

作者头像 李华
网站建设 2026/4/7 6:22:55

折线图的奇妙变奏:四种创意可视化方法

想象一下折线图就像一条普通的公路&#xff0c;它能带我们从A点到达B点。 但有时我们需要更特别的路线&#xff1a;环岛、盘山公路、波浪形赛道或螺旋上升的通道。 在数据可视化中&#xff0c;标准的折线图有时无法充分展示数据的特性&#xff0c;这时我们就需要一些创意变种。…

作者头像 李华
网站建设 2026/4/2 4:22:15

Kotlin协程进阶王炸之作-Kotlin的协程到底是什么

Kotlin协程进阶之不得不看 kotlin协程推出至今已成为 Android 开发人员的必备技能&#xff0c;但直到今天仍然有很多关于kotlin协程底层的争议。本篇文章围绕kotlin协程底层结合着一些基础讲解&#xff0c;希望可以探究明白kotlin到底是什么&#xff0c;当然&#xff0c;笔者知…

作者头像 李华
网站建设 2026/4/5 20:12:26

学霸同款10个一键生成论文工具,研究生高效写作必备!

学霸同款10个一键生成论文工具&#xff0c;研究生高效写作必备&#xff01; AI 工具如何助力论文写作&#xff0c;提升效率与质量 在研究生阶段&#xff0c;论文写作是一项不可避免的任务&#xff0c;而随着人工智能技术的不断进步&#xff0c;AI 工具已经成为许多学生的得力…

作者头像 李华
网站建设 2026/4/7 13:32:52

一个月内面了30家公司,薪资从18K变成28K,真行啊····

工作3年&#xff0c;换了好几份工作&#xff08;行业流行性大&#xff09;&#xff0c;每次工作都是裸辞。朋友都觉得不可思议。因为我一直对自己很有信心&#xff0c;而且特别不喜欢请假面试&#xff0c;对自己负责也对公司负责。 但是这次没想到市场环境非常不好&#xff0c;…

作者头像 李华