Vuex
全局状态管理器,可以在项目的任何一个组件中去获取和修改,修改可以得到全局响应的变量
vue-cli2
项目中安装vuex,使用npm install vuex --save
安装成功后,在src目录下新建一个store文件,里面创建一个js文件
在js文件中写入:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const STORE = {
state: {},
getters: {},
mutations: {},
actions: {}
}
export default new Vuex.Store(STORE)
然后在main.js文件中引入 store 并注册到 vue 实例中
import Vue from 'vue'
import App from './App.vue'
import store from './store' // 引入store
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store, // 注册到实例中
}).$mount('#app')
vuex的文件配置到这里就完成了
现在再回去看store文件里的参数,这几个对象就是vuex五大核心:
State:可全局访问的对象
Getter:和vue的computed一样,用来实时监听state的值的变化(最新状态)
Mutation:存放改变state值的方法(同步)
Action:触发mutations里面的方法(异步)
module:模块
State
State是存储在Vuex中的数据对象,和Vue实例中的data一样。只不过State是可以全局访问的。
定义stata对象,直接在state
里面定义 key:val
,它可以定义任意数据类型
state: {
name:'State',
num: 1,
arr: ["1","2","3"],
obj: {
ob1:'1',
ob2:'2'
},
bool: true
},
在页面中获取state的值 使用this.$store.state
computed: {
state() { return this.$store.state }
},
mounted(){
console.log(this.state)
}
在这里state
通常都是挂载到computed
计算属性上,这样当state的值发生改变的时候都能及时的响应。
当然也能用到 watch
去监听
这样就能获取到在
state
中定义的数据
State中的辅助函数 mapState
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性
import Vue from 'vue'
// 引入 mapState辅助函数
import { mapState } from 'vuex'
export default {
computed:{
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
name: state => state.name, // 获取到state中的name
num: state => state.num, // 获取到state中的num
ArrObj: state => [state.arr,state.obj] // 获取到state中的 arr 和 obj
})
},
mounted(){
console.log('name:',this.name)
console.log('num:',this.num)
console.log('ArrObj:',this.ArrObj)
},
}
输出
Getter
Vuex 允许我们在 store 中定义getter
(可以认为是 store 的计算属性)。就像计算属性computed
一样,getter
的返回值会根据它的依赖被缓存起来,且只有当它的依赖值(state
中的属性)发生了改变才会被重新计算。
Getter的作用就是用来实时监听state的值的变化
定义Geters对象
使用 state
作为其第一个参数
可以使用其他getter
函数作为第二个参数
state: {
name:'State',
num: 1,
arr: ["1","2","3"],
obj: {
ob1:'1',
ob2:'2'
},
bool: true
},
getters: {
// 获取state中的name
getName (state) { return state.name }, // 把state作为第一参数
// 获取state中的arr
getArr: state => { return state.arr },
// 获取state中的obj
getObj: state => { return state.obj },
// 获取getters中的 getArr 和 getObj
getArrObj: (state,getters) => { // 把getters作为第二参数
return {
"arr":getters.getArr,
"obj":getters.getObj
}
}
},
在页面中使用getters,使用this.$store.getters
mounted(){
console.log('Getters:',this.$store.getters)
console.log('getArrObj:',this.$store.getters.getArrObj)
}
Getters中的辅助函数 mapGetters
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
import Vue from 'vue'
// 引入 mapGetters 辅助函数
import { mapGetters } from 'vuex'
export default {
computed:{
// 使用对象展开运算符将此对象混入到外部对象中
...mapGetters([
'getName', // 获取到 getters 中的 getName
'getArr', // 获取到 getters 中的 getArr
'getArrObj' // 获取到 getArrObj 中的 getArrObj
])
},
mounted(){
console.log('getName:',this.getName)
console.log('getArr:',this.getArr)
console.log('getArrObj:',this.getArrObj)
},
}
输出
Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
使用 state
作为第一个参数
state: {
name:'State',
},
mutations: {
newName(state){
return state.name = 'newState'; // 改变state.name的值
}
},
使用 this.$store.commit('方法名')
触发mutations中的方法
mounted(){
console.log('name改变前:',this.$store.state.name)
this.$store.commit('newName') // 启动mutations
console.log('name改变后:',this.$store.state.name)
},
输出
而第二参数官方解释叫 提交载荷(Payload)
可以向 store.commit
传入额外的参数,即 mutation
的 载荷(payload)
简单来说就是可以在在第二参数里传入额外的参数
这里还是用name来做例子
state: {
name:'State',
},
mutations: {
newName(state,playload){
// 传入第二参数
return state.name = playload;
}
},
mounted(){
// commit传入第二参数
this.$store.commit('newName','哈哈哈哈')
console.log('name修改后:',this.$store.state.name)
this.$store.commit('newName',{'name':'啊啊啊啊','age':'116'})
console.log('name修改后:',this.$store.state.name)
},
输出
在 Vuex 中,mutation 必须是同步函数
Action
Action 可以包含任意异步操作,Action的作用就是异步触发Mutations
定义action对象
接收一个context
参数和一个要变化的形参
context
与store
实例具有相同的方法和属性,所以他可以执行context.commit("")
,也可以使用 context.state
和 context.getters
来获取 state
和 getters
。
state: {
name:'State'
},
mutations: {
newName(state,playload){
//传入第二参数
return state.name = playload;
}
},
actions: {
actionName(context){
// context的作用与组件上的this.$store作用一样,但两者还是会有区别
return context.commit('newName',100000000)
}
}
使用this.$store.dispatch("方法名")
方法执行Actions
mounted(){
console.log('name修改前:',this.$store.state.name)
this.$store.dispatch("actionName")
console.log('name修改后:',this.$store.state.name)
},
输出
同样Action还支持载荷方法,传入第二形参
actions: {
actionName(context,playload){
return context.commit('newName',playload)
}
}
mounted(){
console.log('name修改前:',this.$store.state.name)
this.$store.dispatch("actionName","qazwsxedc")
console.log('name修改后:',this.$store.state.name)
},
输出
Module
其中 module 的作用是可以把 store 分割成模块(module),每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const MODULEA = {
state: {},
getters: {},
mutations: {},
actions: {}
}
const MODULEB = {
state: {},
getters: {},
mutations: {},
actions: {}
}
export default new Vuex.Store({
modules: {
storeA: MODULEA ,
storeB: MODULEB
}
})
主要是为了解决由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
简单来说就是可以把vuex模块化