一、Vuex简单介绍

Vuex 是 Vue.js 的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。【一句话:用于多个组件共享数据——通信】

官网:https://vuex.vuejs.org/zh/

(1)Vuex 的主要特点包括:

  • 单一状态树:Vuex 使用单一状态树——即一个对象树来存储应用中所有组件的状态,并且保证状态以统一的方式任何组件都可以获取到。
  • 提交 mutation:唯一改变 Vuex 状态的方法是提交 mutation。 mutation 里面的方法都是同步方法。
  • Action:Action 可以包含任意异步操作。
  • 模块化:Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块等等。
  • 严格模式:Vuex 可以开启严格模式,让状态变更更加可预测。
  • 插件机制:可以通过 Vuex 插件来扩展 Vuex 的功能。

(2)Vuex 作用:

  • 集中状态管理,方便多个组件访问和修改状态
  • 可记录每次状态改变的操作,方便追踪bug
  • 能深入理解组件间关系和状态流动
  • 实现路由状态管理
  • 与其他库整合,实现更复杂的业务需求

(3)Vuex包含了Store概念:

Store模式——状态管理

Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式store为所有的组件提供共享状态。

Store在Vuex中的含义和作用是:

  • Store就是保存状态的对象实例。
  • 使用Vuex需要先创建一个Store实例,这个实例用来保存整个应用的状态树。
  • Store包含以下属性和方法:
    • state: 储存应用中的数据
    • getters: 获取state计算后的子状态
    • mutations: 更改state的唯一方法
    • actions: 包含了操作状态的方法,可异步处理
    • modules: 将Store分割成不同的模块
  • 在Vue组件中使用connect将Store与组件连接起来。
  • 组件可以通过commit()触发mutation进行状态更新。
  • 也可以dispatch()触发action进行异步操作。

Store就是Vuex中管理状态的单一资源库。需要对外暴露Store实例,供组件从中读取和修改状态值。Store提供了Vuex的数据管理能力,所有组件共享同一Store实例和状态。

(4)使用 Vuex 需要以下步骤:

Vue2中要用vuex的3版本,Vue3中要用vuex的4版本。

  1. 引入 Vuex
  2. 创建 store 对象,包含状态(state)、修改状态的方法(mutation)、以及操作状态的方法(action)等。
  3. 在 Vue 实例中注入 store 对象
  4. 组件通过调用 store 里的方法来改变状态,比如 this.$store.commit(‘mutation类型’,’参数’)
  5. 组件通过计算属性对状态的监听订阅而更新视图
  6. 创建模块分割代码,区分不同需求的模块管理
  7. 使用插件进行功能增强

(5)Vuex中的store文件一般建议放在src目录下的store文件夹里:

1
2
3
4
5
6
7
8
9
10
11
12
13
src
|- store
|- index.js // store文件
|- modules
|- cart.js # 购物车模块
|- products.js # 产品模块
|- ...
|- components
|- ...
|- views
|- ...
|- App.vue
|- main.js

把store文件存放在src/store目录下有以下几点好处:

  • 便于管理和组织,将状态管理代码与组件代码隔离开来。
  • store目录下可以创建多个modules文件来对store进行模块化管理。
  • 其他文件可以使用相对路径或引入store,比如import store from '@/store'
  • 在vue-cli脚手架中默认使用store目录,符合常见结构规范。
  • store目录后续也可以考虑使用命名空间来进一步划分store代码块。

除此以外,也可以选择直接在src目录下创建store.js文件。但建议采用Store文件夹管理独立的方式,有利于维护扩展。

二、Vue3中Vuex的变化

Vuex 的工作原理和主要概念在 Vue 3 中保持不变:

  • 仍然有单一状态树(single state tree)的架构;
  • 使用 store.commit 触发同步 mutation;
  • 使用 store.dispatch 触发异步 action;
  • 通过 computed property 从 store 中获取 state;
  • 定义 getter 过滤和加工 state;
  • 模块化代码支持;
  • 严格模式可以增强可预测性;
  • 仍然提供插件系统进行代码增强。

与 Vue 2 不同的是,Vuex 在 Vue 3 中的使用需要根据 Vue 3 的一些改变进行调整:

  • store 不再作为 Vue 实例的其中一个选项 property 流入组件;
  • 需要使用 new Vuex.Store() 显式创建 Store 实例;
  • 使用 storeToRefs 从 store 中引用状态;
  • 组件挂载时使用提供的 store 而非 this.$store。

三、使用

1、基本使用

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //引用Vuex
    Vue.use(Vuex)

    const actions = {
    //响应组件中加的动作
    jia(context,value){
    // console.log('actions中的jia被调用了',miniStore,value)
    context.commit('JIA',value)
    },
    }

    const mutations = {
    //执行加
    JIA(state,value){
    // console.log('mutations中的JIA被调用了',state,value)
    state.sum += value
    }
    }

    //初始化数据
    const state = {
    sum:0
    }

    //创建并暴露store
    export default new Vuex.Store({
    actions,
    mutations,
    state,
    })
  2. 组件中读取vuex中的数据:$store.state.sum

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

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

2、Vue2

1
2
# 安装vuex3
npm i vuex@3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>

<script>
import { mapState, mapActions } from 'vuex'

export default {
computed: mapState(['count']),
methods: mapActions(['incrementAsync'])
}
</script>

3、Vue3

1
npm install vuex@next --save
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// store.js
import { createStore } from 'vuex'

export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
incrementAsync({ commit }) {
// ...
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
<p>Count: {{ count }}</p>
</div>
</template>

<script setup>
// pinia是vue3中最新的状态管理工具
import { storeToRefs } from 'pinia'

const { count } = storeToRefs(store)

function increment() {
store.commit('increment')
}
</script>

主要区别在于Vue3中不再使用this.$store,而是通过storeToRefs获取状态和方法。