vuex知识总结
一、什么是vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
二、state
大白话:专门用来声明全局变量的地方
官方术语:state是存放所有公共状态的属性,如果有一个公共状态数据,只需要定义在state对象中
声明:
state:{
a:123,
count:0
}
使用:
$store.state.count
优化使用:
<h1>{{myCount}}</h1>
<script>
computed:{
myCount() {
return this.$store.state.count
}
}
</script>
辅助函数使用:
<h1>{{count}}</h1>
import { mapState } from "vuex"
computed: {
...mapState(["count"])
}
使用场景:
当一个变量需要在多个vue文件中使用的时候,这个变量可以声明在state中成为一个全局变量
三、mutations
大白话:mutations是专门用来修改state中的变量的对象(属性)
官方术语:state数据的修改只能通过mutations,并且必须是同步更新(也就是里面不能有异步代码)
定义:(定义mutations,以及定义修改count变量的函数)
mutations: {
addCount(state, payload) {
// state: 这个是内置的参数,指的就是mutations同级的state属性
// payload: 调用函数时传入的参数
state.count += payload
}
}
使用:
<button @click="$store.commit('addCount', 5)">
优化使用:
<button @click="changeCount(6)">
// 通过事件处理函数来调用commit方法,实现修改count的值
methods: {
changeCount(num) {
this.$store.commit("addCount", num)
}
}
辅助函数
<button @click="addCount(6)"> // 直接使用解构出来的addCount函数
import { mapState, mapMutations } from "vuex"
methods: {
changeCount(num) {
this.$store.commit("addCount", num)
}
// 通过辅助函数引入addCount函数,并把addCount解构到methods中
...mapMutations(["addCount"])
}
使用场景:
当我们需要修改state中变量的值的时候,此刻需要用到mutations
四、actions
大白话:actions就是可以通过异步操作,调用mutations中的函数,从而修改state中的变量。
官方术语:state是存放数据的,mutations是同步更新数据,actions则辅助进行异步操作。
定义:
actions: {
getAsyncCount(store, num) {
// store: 内置的参数,指的是vuex.store的实例
// 需求:1秒后更新state中count的值
setTimeout(() => {
// 因为store已经通过参数可以获取到了,这里可以直接通过store调用commit方法
store.commit("addCount", num)
}, 1000);
}
}
使用:
// 点击按钮的时候,通过dispatch方法调用actions中的函数从而更新state中变量的值
<button @click="$store.dispatch('getAsyncCount, 10')">
优化使用:
<button @click="changeCount(4)">
methods: {
changeCount(num) {
this.$store.dispatch("getAsyncCount", num)
}
}
辅助函数:
<button @click="getAsyncCount(100)">
import { mapActions } from "vuex"
computed: {
changeCount(num) {
this.$store.dispatch("getAsyncCount", num)
}
...mapActions(["getAsyncCount"]) // 数组的形式通过辅助函数把actions里面函数导入,然后通过解构方法把函数解构到methods中
}
使用场景:
当我们需要修改state中变量的值的时候,此刻需要用到actions
五、getters
大白话:除了state可以声明全局变量之外,还可以利用getters声明全局变量,只不过getters声明的变量是从state派生出来的,getters就相当于vue中的computed计算属性。
官方话术:除了state之外,有时我们还需要从state中派生出一些状态,这些状态依赖state,此时会用到getters
定义:
<h1>{{ $store.getters.filterList }}</h1>
state: {
a: 123,
count: 0,
list: [1,2,3,4,5,6,7,8,9,10]
}
getters: {
// 声明变量,值是一个函数,这个函数必须要有返回值
// 需求:页面中需要用到state中的list数组中大于5的数据
filterList: (state) => {
// state:内置参数,指的就是和getter同级的state属性
return state.list.filter(item => item > 5)
}
}
优化使用:
<h1>{{ filterList }}</h1>
computed: {
// getters中属性的优化使用可以利用计算属性进行简化使用
filterList() {
return this.$store.getters.filterList
}
}
辅助函数:
<h1>{{ filterList }}</h1>
import { mapGetters } from "vuex"
computed: {
// 通过辅助函数获取到getters中的变量,然后解构到计算属性中
...mapGetters(["filterList"])
}
使用场景:
// 简化state中值的获取
<h1>{{ $store.getters.pr }}</h1>
state: {
obj: {
student: {
name: "小明",
age: 12,
address: {
pr: "广东省"
}
}
}
}
getters: {
pr: (state) => {
return state.obj.student.address.pr
}
}
六、module
大白话:分模块管理我们的全局变量,这样有利于项目的后期维护。
官方术语:由于单一状态树,应用的所有状态会集中在一个比较大的state对象中,当应用变的复杂的时候,代码就变的相当臃肿了,vuex会变的越来越难维护,因此就有了vuex的模块化。
定义:
modules: {
user: {
state: {
token: "12345"
},
mutations: {},
actions: {},
getters: {},
modules: {}
},
setting: {
state: {
name: "vuex实例"
}
}
}
使用:
<h1>获取user模块中的token:{{ $store.state.user.token }}</h1>
<h1>获取setting模块中的name:{{ $store.state.setting.name }}</h1>
利用getters简化模块中变量的使用:
getters: {
pr: (state) => {
return state.obj.student.address.pr
},
token: state => state.user.token,
name: state => state.setting.name
}
<h1>获取user模块中的token:{{ token }}</h1>
<h1>获取setting模块中的name:{{ name }}</h1>
import { mapGetters } from "vuex"
computed: {
// 通过辅助函数将token和name解构到计算属性中
...mapGetters(["token", "name"])
}
默认情况下:模块中mutations,actions,getters中声明的变量都是挂载到全局命名空间的
<button @click="$store.commit('updateToken')">
<button @click="$store.dispatch('aysncChangeToken')">
modules: {
user: {
state: {
token: "12345"
},
mutations: {
updateToken(state) {
state.token = 666
}
},
actions: {
aysncChangeToken(store) {
setTimeout(() => {
store.commit("updateToken")
}, 1000)
}
},
getters: {},
modules: {}
},
setting: {
state: {
name: "vuex实例"
}
}
}
命名空间 - 加锁
默认情况下每个模块中的mutations,actions,getters,声明的变量或者函数都是全局命名空间的,因此不具备封闭性(不具备独立空间),如果想要让每个模块都具有独立的命名空间,则需要给模块添加namespaced属性且值为true,此刻模块中的mutations,actions,getters,声明的变量或者函数都成为局部的变量或函数(相当于给模块添加了一道锁),访问他们的时候必须添加模块名才可以访问成功。
<button @click="$store.commit('user/updateToken')">
<button @click="$store.dispatch('user/aysncChangeToken')">
modules: {
namespaced: true, // true表示为user模块加了一道锁
user: {
state: {
token: "12345"
},
mutations: {
updateToken(state) {
state.token = 666
}
},
actions: {
aysncChangeToken(store) {
setTimeout(() => {
store.commit("updateToken")
}, 1000)
}
},
getters: {},
modules: {}
},
setting: {
state: {
name: "vuex实例"
}
}
}
独立模块 - 辅助函数的使用:
import { mapState, mapMutations } from "vuex"
methods: {
// 调用具有独立空间的模块中的函数,需要通过以下语法获取
// 语法:mapMutations(模块名, ["函数名"])
// 通过辅助函数把user模块中的updateToken函数解构到methods中,然后就可以直接使用了
...mapMutations("user", ["updateToken"])
}