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 里计算属性名'])
以上就是关于 Vue 中 Vuex 的基础和应用方法,希望对大家有帮助。