超浅析vuex和它的核心概念(复习笔记)

162 阅读4分钟

超浅 析vuex和它的核心概念(复习笔记)

vuex是什么?

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

​ 以上是官网的介绍 (o゚v゚)ノ ,我大概就懂了一半,用大白话说就是 =>

​ vuex是一个动态的数据库,类似组件中国的data,但这个data中的数据全项目都可以调用,当然,你用它的东西就得守他的规则,为了保证数据的安全和方便维护,它有一些自己的规则ヾ(≧▽≦*)o

vuex解决了什么问题

  1. 我们都知道vue中传递数据很麻烦,特别是族谱隔得特别远, vuex 就专门解决这种组件间关系复杂,传值不方便的问题,它提供了一个共享的数据仓库,让组件间数值的传递更加快捷,同时,也解决了大量的传值带来的代码臃肿问题.

    1. vuex在使用的过程中,提供了一系列的规则,以保证数据的安全性,同时,也使得调试起来更容易
    2. 异步操作的处理:应用程序中需要处理异步操作(如API调用)时,可能会出现回调地狱等问题。Vuex提供了一种机制来处理这些异步操作,使得代码更加整洁和可读。

vuex的核心概念

1.state

​ 作用: 用于存储需要共享的数据

定义:
	export default {
        state: {
            a:'xxx'
        }
	}
使用:
	//在template中调用
		$store.state.数据名

	//在script中调用
		this.$store.state.数据名

	//在js文件中
	//1.引入store
		import store from '@/store'
	//2.调用
		store.state.数据名

对于vue实例原型中方法在不同位置使用的多种情况可以参考上面state的写法,以下统一使用在script中的情况

使用计算属性简写:
	computed: {
        数据名() {
            return this.$store.state.数据名
        }
	}
	//这样就可以直接通过计算属性的方式来调用了
使用辅助函数 mapState() 调用:
//1.先引入
	import { mapState } from 'vuex'

//2.调用mapState,传入state中的公共数据(一般放在数组或对象中)
	mapState(['数据名1','数据名2'...])  /  mapState({xxx, xxy,..})

//3.mapState的返回值是对象,内部放有 返回调用state中定义的数据 的计算属性,且计算属性名与mutation中的相同
	computed: {
    	...mapState(['数据名1','数据名2'...])
	}

2.mutations

​ 作用: vuex要求,state中的数据必须使用mutation中的方法更新,因此,所有操作state中数据的方法都应该写在这里

​ 扩展:

​ 严格模式: 在创建Store实例的时候,在配置对象里添加 strict: true

​ 严格模式会监听状态树,阻止非法的数据修改,导致性能的消耗,所以在生产模式不要开启

定义:
	export default {
        state: {
          a: 1  
        },
        mutations: {
            //这里使用es6的简写
            do(state, payload){
                state.a = 2
            }
        }
	}

注意点: 
	1. 第一个参数必须是state,是的,就是头上那个state
    2. 第二个参数是payload(不一定要用这个名字),用于接收参数, 不过要注意=> payload是mutations中方法唯	二的形参,也就是说多个实参需要用对象包裹起来传过来
	3. mutationss中的方法不能进行异步操作

​ 其实还有一个很有意思的东西,就是vuex的调试工具devtool, 这玩意只能监听同步的数据操作,所以它就一直在偷窥mutations里面的成员(dio画风的devtool

​ 顺便一提,尽管vuex希望我们不要在mutations中做除了修改state中数据以外的其他操作,但实际上我们还是经常用它去顺便设置token本地持久化存储(´。_。`)

使用:
	//调用mutations的方法,必须传入方法名,如果需要传参,则将所有的参数放进载荷对象,将这个对象传过去
		this.$store.commit('方法名', payload)
执行流程:

​ 1.创建store实例 ​ 2.配置项中添加mutations属性,并在其中添加方法 ​ 3.在组件中通过 this.$store.commit('xxx') 来调用 mutations中 的方法 ​ 4.mutations中的函数修改 state 中的数据,动态的渲染到使用这个数据的组件中

使用辅助函数 mapmutations() 调用:
//1.先引入
	import { mapMutations } from 'vuex'

//2.调用mapMutations,传入mutations中的方法名(一般放在数组或对象中)
	mapMutations(['方法名1','方法名2'...])

//3.mapMutations的返回值是对象,内部放有 返回调用mutation中定义的方法 的函数,且函数名与mutation中的相同
	methods: {
    	...mapmutations(['数据名1','数据名2'...])
	}

3.actions

​ 作用: 专门用于处理需要执行异步操作的方法,总之,请求/定时器之类的异步操作请丢这里

​ 注意: actions 内是不可以直接操作state的!

定义:
	1.定义mutation中的修改state方法
	const store = new Vuex.Store({
    	state: {
        	count: 100
    	},
    	mutations: {
    		//第一个形参必须是state!!!
        	addCount(state, payload) {
            	state += payload.a
            	state += payload.b
        	}	
    	}
	})

	2.定义actions中的异步方法
	const store = new Vuex.Store({
    	state: {
        	count: 100
    	},
    	mutations: {
    		//第一个形参必须是state!!!
        	addCount(state, payload) {
            	state += payload.a
            	state += payload.b
        	}
    	},
    	actions: {
    		//第一个参数必须是context,可以简单理解为简化的state对象,也有commit方法来调用mutations
        	addCountAsync(context, payload) {
            	setTimeout(() => {
            		context.commit('addCount', payload)
        		}, 2000)
        	}
    	}
	})
调用:
	3.通过this.$store.dispatch('方法名', 实参) 来调用actions中的方法,获取结果后通过 					context.commit('方法名', 实参) 调用mutations中的方法 修改state中的数据

	4.动态数据显示

注意,dispatch方法会返回一个promise对象,可以在直接 this.$store.dispatch('方法名', 实参).then( ) 在请求成功过后在执行后面代码,当然async / await 也行

辅助函数: mapActions

原理和使用方法同 mapMutations

4.getters

​ 作用:公共的计算属性,

​ 注意,getters和computed不同点在于getters是只读的

定义:
const store = new Vuex.Store({
    	state: {
        	count: 100
    	},
    	getters: {
            //定义一个计算两数之和的计算属性
        	sum(state) {
            	return state.a + state.b
        	}	
    	}
	})
调用:
this.$store.getters.sum
使用计算属性mapGetters调用:
//1.先引入
	import { mapGetters } from 'vuex'

//2.调用mapGetters,传入getters中的计算属性
	mapGetters(['数据名1','数据名2'...])  /  mapGetters({xxx, xxy})

//3.mapState的返回值是对象,内部放有 返回调用state中定义的数据 的计算属性,且计算属性名与mutation中的相同
	computed: {
    	...mapGetters(['数据名1','数据名2'...])
	}

5.modules

​ 作用:用于模块化臃肿的store根文件

定义:
// 1.先引入模块
import user from './mudules/user'
// 2.将模块注册进来
const store = new Vuex.Store({
    	modules: {
            user
    	}
	})

因为模块中的方法/属性最后都要导入到 store 中,为了防止名字相同导致的多个调用,所以vuex可以开启命名空间,隔离开不同的组件

//组件导出时,导出对象加上namespaced属性
export default {
    namespaced: true    //记得单词最后加那个 d
}

在打开vuex的调试面板时,开启命名空间的模块有明显标识,要注意有没有开,开发时默认所有模块必开

开启命名空间之后,调用模块中的方法发生了改变,具体如下

调用:
//调用组件中的 state
	this.$store.state.模块名.state   通过模块名调用对应模块的函数
//调用组件中的 getters
	this.$store.getters['模块名/计算属性名', payload]
//调用组件中的 mutations
	this.$store.commit('模块名/计算属性名', payload)
//调用组件中的 actions
	this.$store.dispatch('模块名/计算属性名', payload)
辅助函数在开启命名空间的模块中的使用:
import { mapState } from '@/store'
import { mapGetters } from '@/store'
import { mapMutations } from '@/store'
import { mapActions } from '@/store'


//调用组件中的 state
	computed: {
        ...mapState('模块名', [ '数据名1','数据名2'...])
	}
//调用组件中的 getters
	computed: {
        ...mapGetters(['模块名/计算属性名1','模块名/计算属性名2'...])
	}
//调用组件中的 mutations
	methods: {
        ...mapMutations(['模块名/方法名1','模块名/方法名2'...]])
	}
//调用组件中的 actions
	methods: {
        ...mapActions(['模块名/方法名1','模块名/方法名2'...]])
	}

本次的内容较多,有错误和不足是在所难免的,如果您发现了我的错误,欢迎您私信我修改,对于我的失误造成的错误,我非常抱歉!