vuex 状态管理详解

556 阅读2分钟

安装

1、使用vue-cli脚手架自助安装。

2、npm安装  npm i vuex -s

vuex5种属性

1. state:vuex的基本数据,用来存储变量。

2. geeter:从基本数据(state)派生的数据,相当于state的计算属性。 

3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。

4. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。

5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

使用

在项目的根目录下新增一个store文件夹,在该文件夹内创建index.js

并在该文件下:

导入  vue import Vue form 'vue'

导入vuex import Vuex form 'vuex'

使用vuex Vue.use('Vuex') 意思是vue来使用

导出

export default new Vuex.store({
	定义存储变量的state
	state:{
		name:"一个不能改变的值"
		}

})

state里面的数据不能直接修改。

直接修改(例如:this.$store.state.name = 'hello')的话不能被VueDevtools所监控到。

使用store

export default new Vuex.store({
	定义存储变量的state
	state:{
		name:"一个不能改变的值"
		}

})

将store挂在到当前vue实例中

import store from 'url'

Vue.config.productionTip = false   //禁用生产消息

new Vue({
	el:'#app',
	store, //这里挂在完成
	router,
	render:h=>h(App)

}).$mount('#app')

可以在组件中调用

<template>
    <div id='app'>
        name:
        <h1>{{ $store.state.name }}</h1>
    </div>
</template>

或者要在组件方法中使用

methods:{
    add(){
      console.log(this.$store.state.name)
    }
}

使用mutations

mutations相当于方法。

在store中定义:mutations

mutations:{
	edit(state,接受参数){
	state.name = '改变值要在这里改,这个方法是同步的'
}

在Mutations的方法中来设置state中的数据。

Vue.set(state,"age",15)
Vue.delete(state,'age')

调用 ,例如在APP.vue的method中

this.$store.commit('edit''需要传的参数') 调用这个方法
this.$store.commit('edit',{age:15,sex:'男'})
另一种调用方式
this.$store.commit({
    type:'edit',
    payload:{
        age:15,
        sex:'男'
    }
})

getters 计算属性(类似于计算属性compute,是用来计算state的)

有两个参数getters(state,getters)

state 当前VueX对象中的状态对象 

getters 当前getters对象,用于将getters下的其他getter拿来用

getters:{
    nameInfo(state){
        return "姓名:"+state.name
    },
    fullInfo(state,getters){
        return getters.nameInfo+'年龄:'+state.age
    }  
}

组件中调用

this.$store.getters.fullInfo

Actions (是mutations的异步调用)

actions只是包装了mutations

Actions中的方法有两个默认参数

context 上下文(相当于箭头函数中的this)对象
payload 挂载参数

由于setTimeout是异步操作,所以需要使用actions
actions:{
    aEdit(context,payload){
        setTimeout(()=>{
            context.commit('edit',payload)
        },2000)
    }
}

组件中调用

this.$store.dispatch('aEdit',{age:15})

可以为我们的异步操作封装为一个Promise对象

aEdit(context,payload){
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                context.commit('edit',payload)
                resolve()
            },2000)
        })
    }

当项目庞大,状态非常多时,可以采用模块化管理模式。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。

models:{
    a:{
        state:{},
        getters:{},
        ....
    }
}

组件内调用模块a的状态:this.$store.state.a

提交或者dispatch某个方法和以前一样,会自动执行所有模块内的对应type的方法

this.$store.commit('editKey')
this.$store.dispatch('aEditKey')

模块中mutations和getters中的方法接受的第一个参数是自身局部模块内部的state

models:{
    a:{
        state:{key:5},
        mutations:{
            editKey(state){
                state.key = 9
            }
        },
        ....
    }
}

getters中方法的第三个参数是根节点状态

actions中方法获取局部模块状态是context.state,根节点状态是context.rootState

合理的store目录

store:.
│  actions.js
│  getters.js
│  index.js
│  mutations.js
│  mutations_type.js   ##该项为存放mutaions方法常量的文件,按需要可加入
│
└─modules
        Astore.js

对应的内容存放在对应的文件中,和以前一样,在index.js中存放并导出store。state中的数据尽量放在index.js中。而modules中的Astore局部模块状态如果多的话也可以进行细分。