2663 字
13 分钟
Vuex 状态管理笔记
Vuex 状态管理详解,涵盖 state、getters、mutations、actions、模块化、map 辅助函数、命名空间等,适合 Vue2/Vue3 项目集中式数据管理。
2026-02-03
0 次
0 人

Vuex#

概念#

​ 在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

1.是什么:

vuex 是一个 vue 的 状态管理工具,状态就是数据

大白话 是一个插件,可以帮我们**管理vue 通用的数据(多组件共享的数据)**

2.场景:

① 某个状态 在 很多个组件 来使用(个人信息)

② 多个组件 共同维护 一份数据(购物车)

3.优势:

① 共同维护一份数据,数据集中化管理

响应式变化

③ 操作简洁(vuex提供了一些辅助函数)

何时使用?#

​ 多个组件需要共享数据时

搭建vuex环境#

  1. 安装vuex

    Terminal window
    npm i vuex@3 //vue2 安装3版本 vue3安装4版本
  2. 创建文件:src/store/index.js

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //应用Vuex插件
    Vue.use(Vuex)
    //准备actions对象——响应组件中用户的动作
    const actions = {}
    //准备mutations对象——修改state中的数据
    const mutations = {}
    //准备state对象——保存具体的数据
    const state = {}
    //创建并暴露store
    export default new Vuex.Store({
    actions,
    mutations,
    state
    })
  3. main.js中创建vm时传入store配置项

    ......
    //引入store
    import store from './store'
    ......
    //创建vm
    new Vue({
    el:'#app',
    render: h => h(App),
    store//传入store配置项
    })

vuex中的配置项#

state(存放数据)#

state-状态,即数据, 类似于vue组件中的data 区别: 1.data 是组件自己的数据 2.state 是所有组件共享的数据

state对象,用于存放数据

const store = new Vuex.Store({
state:{
count:0
},
}

strict(严格模式)#

strict: true:开启严格模式

vuex不允许直接用*store.state.num++这类直接修改state中的数据的方法来修改state中的值,虽然代码执行不会报错,state中的数据也会改变,但是后期会影响维护,这是不规范的操作2.开启严格模式后,若执行store.state.num++*这类直接修改`state`中的数据的方法来修改`state`中的值,虽然代码执行不会报错,`state`中的数据也会改变,但是后期会影响维护,这是**不规范的操作**。 2.开启严格模式后,若执行*store.state.num++*这类直接修改state中的数据时,会提醒用户报错,不配置将不会提醒 注意:上线时要关闭严格模式,不然会消耗性能

getters(存放加工state中的数据)#

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工,类似于Vue中的计算属性,区别在于,因为只能获取,不能修改,修改需要用mutations

  2. 基本使用:必须要有返回值,返回值就是定义该属性的值,类似计算属性(computed)

    //创建并暴露store
    export default new Vuex.Store({
    ......
    getters:{
    bigSum(state){
    return state.sum * 10
    }
    }
    })
  3. 组件中读取/访问数据:$store.getters.bigSum

mutations(存放方法)#

  1. mutations 对象,对象中存放修改 state 的方法,方法中只能有两个参数,第一个是store里面的state,第二个是this.$store.commit('函数名',参数)传的参数,只能传一个参数,需要传多个参数时,可以将参数改为对象或数组的形式传。

  2. 注意mutations 必须是同步的(便于监测数据变化,记录调试)

    const store = new Vuex.Store({
    state:{
    count:0
    },
    // 定义mutations
    mutations:{
    //第一个参数是当前store的state属性,第二个数是提交调用commit传的参数
    函数名(state参数) {
    state.count += 参数
    }
    }
    })

    2.组件中提交调用 mutations

    this.$store.commit('函数名',参数)

actions(存放处理异步的方法/函数)#

说明: mutations 必须是同步的(便于监测数据变化,记录调试),处理异步必须使用actions,并且需要修改state中的数据时需要和mutations搭配使用,处理异步:通常是发请求

参数说明:第一个参数是context(上下文),第二个参数是$store.dispatch('方法名',参数)传入的参数

Context(上下文)#

  1. 上下文(Context)的概念:在计算机科学中,上下文通常指的是在某一特定时间点或操作点上的环境信息或状态。在Vuex的actions中,context 就是这样一种环境信息,它包含了与store相关的所有方法和属性,使得在actions中能够访问到这些资源和能力。
  2. 包含的方法和属性
    • commit:用于提交一个mutation,从而更改应用的状态。
    • dispatch:用于分发一个action,可以包含异步操作。
    • getters:用于访问store中的getter。
    • state:直接访问store的state对象。
    • rootStaterootGetters(在模块化的store中):用于访问根节点的state和getters。
actions: {
// 处理异步的方法
asyncChangeNum (context, num) {
// 多数时候是发送请求
setTimeout(() => {
context.commit('mutations里面的方法', num)
}, 1000)
}
}

组件中提交调用:actions

$store.dispatch('处理异步的方法',参数)

基本使用#

  1. 初始化数据、配置actions、配置mutations,操作文件store.js

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //引用Vuex
    Vue.use(Vuex)
    //创建并暴露store
    export default new Vuex.Store({
    // 开启严格模式,vuex不允许直接用store.state.属性的方法来修改state中的值,
    // 开启严格模式后,会提醒用户报错,不配置将不会提醒
    // 注意:上线时要关闭严格模式,不然会消耗性能
    strict: true,
    // state状态,即数据,类似于vue组件中的data
    // 区别:
    // 1.data 是组件自己的数据
    // 2.state 是所有组件共享的数据
    state = {
    sum:0
    },
    actions= {
    // 响应组件中加的动作
    jia(context,value){
    // console.log('actions中的jia被调用了',miniStore,value)
    context.commit('JIA',value)
    },
    },
    mutations = {
    // 执行加
    JIA(state,value){
    // console.log('mutations中的JIA被调用了',state,value)
    state.sum += value
    }
    },
    })
  2. 组件中读取vuex中的数据:$store.state.sum

  3. JS中读取vuex中的数据:store.state.sum

  4. 组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)$store.commit('mutations中的方法名',数据)

    备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

四个map方法的使用#

mapState方法:#

用于帮助我们映射state中的数据为计算属性

computed: {
//借助mapState生成计算属性:Vuex中state的属性名、school、subject(对象写法,改名)
...mapState({组件使用的属性名:'Vuex中state的属性名',school:'school',subject:'subject'}),
//借助mapState生成计算属性:Vuex中state的属性名、school、subject(数组写法)
...mapState(['Vuex中state的属性名','school','subject']),
},

mapGetters方法:#

用于帮助我们映射getters中的数据为计算属性

computed: {
//借助mapGetters生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'}),
//借助mapGetters生成计算属性:bigSum(数组写法)
...mapGetters(['bigSum'])
},

mapMutations方法:#

用于帮助我们生成与mutations对话的方法,即:生成包含$store.commit(xxx)的函数

methods:{
//靠mapActions生成:Vuex中mutations的方法名、decrement(对象写法)
...mapMutations({组件使用的方法名:'Vuex中mutations的方法名',decrement:'JIAN'}),
//靠mapMutations生成:Vuex中mutations的方法名、JIAN(数组写法)
...mapMutations(['Vuex中state的方法名','JIAN']),
}

备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

mapActions方法:#

用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

methods:{
//靠mapActions生成:incrementOdd、incrementWait(对象写法)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
//靠mapActions生成:incrementOdd、incrementWait(数组写法)
...mapActions(['jiaOdd','jiaWait'])
}

四个map的注意点#

  1. mapStatemapGetters都应该放到组件的computed中,因为vuex的设计初衷是为了响应式共享数据,若放到组件的data中,vuex中的state数据将不会是响应式的。
  2. mapMutationsmapActions都放在组件的methods

模块化#

目的:让代码更好维护,让多种数据分类更加明确。维护时只需要根据所属模块来修改即可。

基本使用:#

  1. 模块拆分

  2. 创建模块:src/store/modules/user.js,根据需求创建模块

    //例: 创建用户模块
    const state = {
    userInfo: {
    name: 'kaka',
    age: 20
    }
    }
    const mutations = {}
    const actions = {}
    const getters = {}
    const users = {
    state,
    mutations,
    actions,
    getters
    }
    // 导出模块
    export default users
  3. 引入模块并配置

    // 引入用户模块
    import users from '@/store/modules/user'
    // 引入设置模块
    import settings from '@/store/modules/settings'
    const store = new Vuex.Store({
    ......
    //配置模块
    modules: {
    users, settings
    }
    })

组件使用模块中的数据和方法#

注意:尽管已经分模块了,但其实子模块的状态,还是会挂到根级别的state 中,属性名就是模块名

组件获取子模块中 state 中的数据#

① 直接通过模块名访问 $store.state.模块名.xxx

② 通过 mapState 映射:

​ 默认根级别的映射 mapState(['xxx'])

子模块的映射 mapstate('模块名',['xxx'])需要开启命名空间(模块中配置 namespaced: true)

组件获取子模块中 getters 中的数据#

① 直接通过模块名访问 $store.getters['模块名/xxx'] ② 通过 mapGetters 映射:

​ 默认根级别的映射 mapGetters(['xxx'])

​ 子模块的映射 mapGetters('模块名',「'xxx'])-需要开启命名空间

组件调用子模块中 mutation方法#

注意:默认模块中的 mutationactions 会被挂载到全局,需要开启命名空间,才会挂载到子模块

① 直接通过 store 调用 $store.commit('模块名/xxx',额外参数)

② 通过 mapMutations 映射:

​ 默认根级别的映射 mapMutations(['xxx'])

​ 子模块的映射 mapMutations('模块名',['xxx'])-需要开启命名空间组件

组件调用子模块中 action方法#

注意 : ** 默认模块中的** mutationactions 会被挂载到全局,需要开启命名空间,才会挂载到子模块

① 直接通过 store 调用 $store.dispatch('模块名/xxx',额外参数) ② 通过 mapActions 映射

​ 默认根级别的映射 mapActions(['xxx'])

​ 子模块的映射 mapActions('模块名',['xxx'])-需要开启命名空间

模块化+命名空间#

  1. 目的:让代码更好维护,让多种数据分类更加明确。

  2. 修改store.js

    const countAbout = {
    namespaced:true,//开启命名空间
    state:{x:1},
    mutations: { ... },
    actions: { ... },
    getters: {
    bigSum(state){
    return state.sum * 10
    }
    }
    }
    const personAbout = {
    namespaced:true,//开启命名空间
    state:{ ... },
    mutations: { ... },
    actions: { ... }
    }
    const store = new Vuex.Store({
    modules: {
    countAbout,
    personAbout
    }
    })
  3. 开启命名空间后,组件中读取state数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
  4. 开启命名空间后,组件中读取getters数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
  5. 开启命名空间后,组件中调用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
  6. 开启命名空间后,组件中调用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),

这篇文章是否对你有帮助?

Vuex 状态管理笔记
作者
蜀枕清何
发布于
2026-02-03
许可协议
CC BY-NC-SA 4.0