一,Vuex 是什么?有什么用
Vuex是一个辅助于 Vue 的状态数据管理库,用于处理Vue开发过程中的重复数据过于冗余无意义从而拖累代码运行效率的一种方案,可以将在同一个入口文件管理下的所有重复的数据、计算、函数定义到一个 store.js(叫什么名字都可以的哈) 的文件中,并且所有受到同一个入口文件管理的组件文件都可以直接访问到其中定义的
数据。
二,Vuex 的特点
Vuex 的一个最大特点就是他是一个公共的响应式数据 , 就是说当其中的数据改变时,那么调用此数据的组件也会随之进行更新操作
例如:token属性是我已经在不同文件中获取的同一个Vuex 属性
那么我在 A.vue 文件中 console.log(token) 与在 B.vue 中的 console.log(token) 打印出来的是同一个值,并且如果在其他文件中对直接 token 进行数据修改,其他的文件会同时进行更新token的数据
比如在 C.vue 中让token的值改为了 "我不是token,是个人" ,那么在 A.vue 和 B.vue 文件中打印出来的token都会是 : "我不是token,是个人"
三,Vuex 中的数据及函数该如何定义
Vuex主要分为四部分,分别是:基础数据 state, 同步函数 mutations,异步函数 actions,计算属性 getters。
1.基础数据 state
类似于data中定义的数据,字符串、数字、函数、对象等等数据都在这里定义,用来储存公共共享的数据源,此处定义的数据仅可以被 mutations 更改
(1) 数据互通
第一种定义方法可以在一个组件改变Vuex中定义的数据源时,那么其他复用过的同一个数据的组件也会同时进行改变更新 ,这是因为组件复用的时候是 以对象的形式进行声明, 引用类型数据会在堆区开拓空间,并在栈区存入一个堆区的地址,所以在改变数据的时候 会直接通过栈区地址找到堆区数据进行更改 其他组件进行获取数据时就会通过栈区地址获取同一个数据
因此就可以使一个数据成为一个所有组件都可以访问复用的公共数据源,但因为复杂数据类型的特点,只开辟了一片空间,大大节省了性能和内存
第一种注册方式如下:
// 注册vuex 公共资源
const store = new Vuex.Store({
// state: 储存共享的数据源,仅可以被 mutations 更改
state: {
text: '我想做个好人',
obj:{
text:'对不起,我是警察'
}
}
})
如上,在注册好的vuex中以对象的形式声明 state,并且以键值对的形式进行声明
(2) 数据复用互不影响
但是如果vuex的数据在需要多次复用,但是用的时候又需要数据相对独立,不得互相影响的时候,此时就可以按照如下写法进行声明,
state: () => ({
// vuex中的模块也是可能进行复用的
// 为了复用的时候 互相不影响 采用同样的函数执行 return对象的形式
token: getToken() || '',
userInfo: {}
})
2.同步函数 mutations
唯一可以同步修改 state的属性的地方,所有同步改动 state 中数据的操作,都要经过 mutations 中定义的函数进行间接操作,例如我想将 state中的num改动为10,那么我不可以直接操作改动num,需要经过如图的 changeNum 这个函数进行操作
// 注册vuex 公共资源
const store = new Vuex.Store({
// state: 储存共享的数据源,仅可以被 mutations 更改
state: {
num: 0
},
// mutations: 同步函数,`唯一` 可以 `同步` 修改 state的 地方
mutations: {
// 定义的同步函数
changeNum( state , '形参' ) {
state.num = 10
}
}
})
在 mutations 中定义的所有函数的形参中,第一个参数为 state 对象,可以通过 state 访问到其中的数据,从第二个参数开始往后,所有的形参都为调用函数所传传递的参数,用以方便操作函数。
mutations 中所定义的函数为同步函数,即被调用则立即直接被主线程执行,不会进入任务队列,在工作中主要负责的功能就是操作 state 中的数据。
而在当前 Vuex 中要想访问到 mutations 中的方法,需要通过 commit 来查找到其中的同步函数名,具体操作请看 异步函数 action
3.异步函数 action
action 是一个异步函数书写的位置,但是涉及到控制 state 中的数据时,不可以直接进行操作改动,必须通过调用 mutations 中的方法来进行间接改动
例如: state 中定义了 num = 1, 如果我想让他在 3秒 后变为 10, 就需要如图操作
// 注册vuex 公共资源
const store = new Vuex.Store({
// state: 储存共享的数据源,仅可以被 mutations 更改
state: {
num: 1
},
// mutations: 同步函数,`唯一` 可以 `同步` 修改 state的 地方
mutations: {
numChange(state,newNum) {
state.num = newNum
}
},
// actions: 异步函数,异步的修改 state,但其不能直接改,最终必须 commit 到指定 mutations 中
actions: {
setNum(store) {
setTimeout(() => {
// commit 用来访问 mutations 中的同步函数
store.commit('numChange',10)
}, 3000);
}
}
})
如图,在 action 中, 定义了一个异步函数为 setNum,他的第一个参数默认为当前 Vuex 根对象,通过 store 中的 commit 可以访问到 mutations 中定义的同步函数,而异步的操作则在当前函数内进行编写, 更改数值的时候进行调用
格式为 : store.commit("同步函数名",传递的参数)
第一个参数默认为根对象,之后的参数都为传递的实参
4.计算函数 getters
getters是 Vuex 的计算属性,以 state数据源 为数据计算而得到结果,类似computed、优势带缓存
定义方法如下:
格式为: return 计算结果
第一个参数默认为 state
const store = new Vuex.Store({
// state: 储存共享的数据源,仅可以被 mutations 同步更改
state: {
num: 50
},
// getters: vuex 的计算属性,数据源 计算而得到,类似computed、优势带缓存
getters: {
changeNum(state) {
const newNum = state.num + 10
return newNum
}
}
})
四,组件访问 Vuex 各项数据函数的方法
首先要在入口文件中 挂上Vuex
import Vuex from 'vuex'
Vue.use(Vuex)
之后在需要使用的组件中进行调用,调用方法分为 直接调用 和 映射使用
state、getters 都是 映射 在 组件 的 computed 中
mutations、actions 都是 映射 在 组件 的 methods 中
1. state 的调用
// 直接调用:
this.$store.state.变量名
// 映射使用 mapState
映射分为对象和数组,对象可以更改映射在当前页面的属性名
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['state变量名']),// 不能改名
...mapState({ // 能改名
留在原地计算属性名: 'state中变量名'
})
}
}
2. mutations 的调用
// 直接调用:
this.$store.commit('mutations中的函数名', 传值)
// 映射使用 mapMutations
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations(['mutations中函数名'])
}
}
3. actions 的调用
// 直接调用:
this.$store.dispatch('actions中的函数名', 传值)
// 映射使用 mapActions
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions(['actions函数名'])
}
}
4. getters 的调用
// 直接调用
this.$store.getters.计算属性的名字
// 映射使用 mapGetters
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['getters中计算属性的名字'])
}
}
// 分模块 调用方法
// state
this.$store.state.模块名.变量名
...mapState("模块名", ['变量名'])
// mutations
this.$store.commit("模块名/mutations里的函数名", 具体值)
...mapMutations("模块名", ['mutations里方法名'])
// actions
this.$store.dispatch("模块名/actions里的函数名", 具体值)
...mapActions("模块名", ['actions里方法名'])
// getters
this.$store.getters['模块名/计算属性名']
...mapGetters("模块名", ['getters里计算属性名'])