Vue 学习笔记 —— Vuex

281 阅读3分钟

笔记内容来自于 b 站教学视频 尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通 张天禹老师

1. 概念

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

image.png

2. 何时使用?

多个组件需要共享数据时

3. 搭建 vuex 环境

  1. 创建文件: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
})
  1. main.js 中创建 vm 时传入 store 配置项
// 引入 store
import store from './store'
......

// 创建 vm
new Vue({
    el: '#app',
    render: h => h(App),
    store
})

4. 基本使用

  1. 初始化数据、配置 actions、配置 mutations,操作文件 store.js
// 引入 Vue 核心库
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
// 应用 Vuex 插件
Vue.use(Vuex)

const actions = {
    // 响应组件中加的动作
    jia(context, value) {
        context.commit('JIA', value)
    }
}

const mutations = {
    // 执行加
    JIA(state, value) {
        state.sum += value
    }
}

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

// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state
})
  1. 组件中读取 vuex 中的数据:$store.state.sum
  2. 组件中修改 vuex 中的数据:$store.dispatch('action 中的方法名', 数据)$store.commit('mutations 中的方法名', 数据)

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

5. getters 的使用

  1. 概念:当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工
  2. store.js 中追加 getters 配置
const getters = {
    bigSum(state) {
        return state.sum * 10
    }
}

// 创建并暴露 store
export default new Vuex.Store({
    ......
    getters
})
  1. 组件中读取数据:$store.getters.bigSum

tips

类比:

  1. state ===> data
  2. getters ===> computed
  3. mutations ===> methods

mutations 必须是同步函数,都是同步事务
actions 可以包含任意异步操作

6. 四个 map 方法的使用

  1. mapState方法:用于帮助我们映射 state 中的数据为计算属性
computed: {
    // 借助 mapState 生成计算属性:sum、school、subject(对象写法)
    ...mapState({sum:'sum', school:'school', subject:'subject'}),
    
    // 借助 mapState 生成计算属性:sum、school、subject(数组写法)
    ...mapState(['sum', 'school', 'subject'])
}
  1. mapGetters方法:用于帮助我们映射 getters 中的数据为计算属性
computed: {
    // 借助 mapGetters 生成计算属性:bigSum(对象写法)
    ...mapGetters({bigSum:'bigSum'}),
    
    // 借助 mapGetters 生成计算属性:sum、school、subject(数组写法)
    ...mapGetters(['bigSum'])
}
  1. mapActions方法:用于帮助我们生成与 actions 对话的方法,即:包含 $store.dispatch(xxx) 的函数
methods: {
    // 靠 mapActions 生成:incrementOdd、incrementWait(对象形式)
    ...mapActions({incrementOdd:'jiaOdd', incrementWait:'jiaWait'}),
    
    // 借助 mapActions 生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd', 'jiaWait'])
}
  1. mapMutations方法:用于帮助我们生成与 mutations 对话的方法,即:包含 $store.commit(xxx) 的函数
methods: {
    // 靠 mapMutations 生成:increment、decrement(对象形式)
    ...mapMutations({increment:'JIA', decrement:'JIAN'}),
    
    // 借助 mapMutations 生成:JIA、JIAN(数组形式)
    ...mapMutations(['JIA', 'JIAN'])
}

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

7. 模块化 + 命名空间

  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 stroe = new Vuex.Store({
    mudules: {
        countAbout,
        personAbout
    }
})
  1. 开启命名空间后,组件中读取 state 数据
// 方式一:自己直接读取
this.$store.state.personAbout.list
// 方式二:借助 mapState 读取
...mapState('countAbout', ['sum', 'school', 'subject'])
  1. 开启命名空间后,组件中读取 getters 数据
// 方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
// 方式二:借助 mapGetters 读取
...mapGetters('countAbout', ['bigSum'])
  1. 开启命名空间后,组件中调用 dispatch
// 方式一:自己直接 dispatch
this.$store.dispatch('personAbout/addPersonWang', person)
// 方式二:借助 mapActions
...mapActions('countAbout', {incrementOdd: 'jiaOdd', incrementWait: 'jiaWait'})
  1. 开启命名空间后,组件中调用 commit
// 方式一:自己直接 commit
this.$store.commit('personAbout/ADD_PERSON', person)
// 方式二:借助 mapMutations
...mapMutations('countAbout', {increment: 'JIA', decrement: 'JIAN'})