Web-Vuex

学习自尚硅谷。

资源

正文

105 Vuex 案例简介

注意

Vuex 是什么

  • 概念:专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 Vue 应用中 多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
  • Github 地址:vuejs/vuex: 🗃️ Centralized State Management for Vue.js.

什么时候使用 Vuex

  • 多个组件依赖于同一状态
  • 来自不同组件的行为需要变更同一状态
webp
webp

106 求和案例_纯 Vue 版

vue
<template>
	<div>
		<Count/>
	</div>
</template>
 
<script>
import Count from './components/Count';
export default {
	name: 'App',
	components: {
		Count
	},
}
</script>
 
<style lang="css">
	button {
		margin-left: 5px;
	}
</style>

107 Vuex 工作原理图

注意

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

webp

这张图展示了 Vuex 的工作原理。

  • Vue Components 相当于顾客,当顾客需要点餐时,可以找 Actions,也可直接找 Mutations(也就是说 Actions 是可以省略的)。

  • Actions 相当于服务员,对顾客点餐的内容做出判断,将信息传给 Mutaions。

  • Mutations 相当于后厨,加工收到的信息,更新给 State。

  • State 相当于菜品,由 Mutations 处理得到,最后交给 Vue Components。

  • Actions、Mutations 和 State 为 Vuex 的组成部分,放在一个 store 中。

注意

什么情况下我应该使用 Vuex?

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 (opens new window) 就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。引用 Redux 的作者 Dan Abramov 的话说就是:

Flux 架构就像眼镜:您自会知道什么时候需要它。

108 搭建 Vuex 环境

警告

  • Vue2 中,要用 Vuex 的 3 版本
  • Vue3 中,要用 Vuex 的 4 版本
shell
npm i vuex@3
added 1 package in 14s

122 packages are looking for funding
  run `npm fund` for details
webp

当 vm 和 vc 对象都具有属性 $store 时,视为 Vuex 安装成功。

如此构建项目:

  • main.js 在使用 new Vue() 创建 vm 时,附带参数 store。
  • 一般 Vuex 的 store 配置在 src/store/index.js 中。

109 求和案例_Vuex 版

还是根据这个图来:

webp
  • $store.state 存储着数据。
  • Vue Components 可以通过 this.$store.dispatch 向 Acitons 发送请求,也可以直接使用 this.$store.commit 向 Mutations 发送请求。
  • Actions 接收请求,可以做一些预处理,通过 this.$store.commit 向 Mutations 发送请求。
  • Mutations 可以对 $store.state 里的值进行修改。
  • $store.state 的值修改后,更新 Vue Components 。

110 Vuex 开发者工具的使用

111 getters 配置项

  • 概念:当 state 中的数据需要经过加工后再使用时,可以使用 getters 再加工。

  • 在 store.js 中追加 getters 配置:

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

javascript
// 该文件用于创建 Vuex 中最为核心的 store
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
 
Vue.use(Vuex)
 
// 准备 actions 用于相应组件中的动作
const actions = {
    addOdd(context, value) {
        console.log('actions addOdd', value)
        if(state.sum % 2 === 1) {
            context.commit('ADD_ODD', value)
        }
    },
    addWait(context, value) {
        console.log('actions addWait', value)
        setTimeout(() => {
            context.commit('ADD', value)
        }, 500)
    }
}
// 准备 mutations 用于修改 state(数据)
const mutations = { 
    ADD_ODD(state, value) {
        // 这里可以做一些异步操作,比如发送请求,修改本地数据等
        // 这里只是简单地修改 state 中的 sum 字段
        console.log('mutations ADD_ODD', value)
        state.sum += value
    },
    ADD(state, value) {
        console.log('mutations ADD', value)
        state.sum += value
    },
    MINUS(state, value) {
        console.log('mutations MINUS', value)
        state.sum -= value
    }
}
// 准备 state 用于存储数据
const state = {
    sum: 0
}
// 准备 getters 用于将 state 中的数据进行加工
const getters = {
    bigSum(state) {
        return state.sum * 10
    }
}
 
// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
 

112 mapState 与 mapGetters

  • mapState 方法:用于帮我们映射 state 中的数据为计算属性。

    javascript
    computed: {
        // 借助 mapstate 生成计算属性:sum、school、subject(对象写法)
        ...mapState({sum: 'sum', school: 'school', subject: 'subject'}),
        // 借助 mapstate 生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum', 'school', 'subject']),
    }
  • mapGetters 方法:用于帮助我们映射 getters 中的数据为计算属性。

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

113 mapActions 与 mapMutations

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

    javascript
    methods:{
    	//靠 mapActions 生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({incrementOdd: 'jiaOdd', incrementWait: 'jiaWait'})
        
    	// 靠 mapActions 生成:incrementOdd、incrementWait(数组形式)
        ...mapActions(['jiaOdd', 'jiaWait'])
    }
  • mapMutations 方法:用于帮助我们生成与 mutations 对话的方法,即:包含 $store.commit(xxx) 的函数

    javascript
    methods:{
    	// 靠 mapActions 生成:increment、decrement(对象形式)
        ...mapMutations({increment:'JIA', decrement;'JIAN'}),
        // 靠 mapMutations 生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }

提示

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

javascript
// 该文件用于创建 Vuex 中最为核心的 store
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
 
Vue.use(Vuex)
 
// 准备 actions 用于相应组件中的动作
const actions = {
    addOdd(context, value) {
        console.log('actions addOdd', value)
        if(state.sum % 2 === 1) {
            context.commit('ADD_ODD', value)
        }
    },
    addWait(context, value) {
        console.log('actions addWait', value)
        setTimeout(() => {
            context.commit('ADD', value)
        }, 500)
    }
}
// 准备 mutations 用于修改 state(数据)
const mutations = { 
    ADD_ODD(state, value) {
        // 这里可以做一些异步操作,比如发送请求,修改本地数据等
        // 这里只是简单地修改 state 中的 sum 字段
        console.log('mutations ADD_ODD', value)
        state.sum += value
    },
    ADD(state, value) {
        console.log('mutations ADD', value)
        state.sum += value
    },
    MINUS(state, value) {
        console.log('mutations MINUS', value)
        state.sum -= value
    }
}
// 准备 state 用于存储数据
const state = {
    sum: 0,
    school: 'Harvard',
    subject: 'Computer Science'
}
// 准备 getters 用于将 state 中的数据进行加工
const getters = {
    bigSum(state) {
        return state.sum * 10
    }
}
 
// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

114 多组件共享数据

javascript
// 该文件用于创建 Vuex 中最为核心的 store
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
 
Vue.use(Vuex)
 
// 准备 actions 用于相应组件中的动作
const actions = {
    addOdd(context, value) {
        console.log('actions addOdd', value)
        if(state.sum % 2 === 1) {
            context.commit('ADD_ODD', value)
        }
    },
    addWait(context, value) {
        console.log('actions addWait', value)
        setTimeout(() => {
            context.commit('ADD', value)
        }, 500)
    }
}
// 准备 mutations 用于修改 state(数据)
const mutations = { 
    ADD_ODD(state, value) {
        // 这里可以做一些异步操作,比如发送请求,修改本地数据等
        // 这里只是简单地修改 state 中的 sum 字段
        console.log('mutations ADD_ODD', value)
        state.sum += value
    },
    ADD(state, value) {
        console.log('mutations ADD', value)
        state.sum += value
    },
    MINUS(state, value) {
        console.log('mutations MINUS', value)
        state.sum -= value
    },
    ADD_PERSON(state, person) {
        console.log('mutations ADD_PERSON', person)
        state.personList.unshift(person)
    }
}
// 准备 state 用于存储数据
const state = {
    sum: 0,
    school: 'Harvard',
    subject: 'Computer Science',
    personList: [
        {id: '001', name: '张三'}
    ]
}
// 准备 getters 用于将 state 中的数据进行加工
const getters = {
    bigSum(state) {
        return state.sum * 10
    }
}
 
// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
webp

115-116 Vuex 模块化 + namespace

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