vuex---七日打卡

854 阅读3分钟

前言: 前段时间在项目中用到了vuex来管理数据,感觉还挺好用,鉴于自己的记性可以媲美"鱼的记忆",就借着这次打卡的机会,记录一下,以便后期查看、巩固。

vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 vuex的交互行为图

vuex分为如下几个部分:

  • state
  • mutations
  • actions
  • getters
  • modules

一、state

state是页面状态管理容器对象。\color{red}{state}是页面状态管理容器对象。集中存储组件中data对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中获取,利用vue的细粒度数据响应机制来进行高效的状态更新。

state使用方法:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
   state:{
       //存放的键值对就是要管理的状态
       name:'hello'
   }
})

export default store

二、mutaitions

mutations是状态改变操作方法。\color{red}{mutations是状态改变操作方法。}是vuex修改state的唯一推荐方法,其他方式在严格模式下将会报错。该方法只能进行同步操作,且方法名只能全局唯一,操作之中会有一些hook暴露出来,以进行state的监控。

mutations使用方法:

mutations方法有默认的形参:([state] [,payload])
比如在App.vue中提交某个mutation时需要携带一些参数给方法使用,可以这样写: App.vue

this.$store.commit('edit',"张三")//edit是在store.js中定义的mutation方法,张三是传递的参数 

store.js

const store = new Vuex.store({
    state:{
        name:'hello'
    },
    mutations:{
        edit(state,payload){
            state.name = payload//这一步就把state中name的值改为了张三
        },
        add(state){
        	Vue.set(state,'age',11)
        }
        delete(state){
        	Vue.set(state,'age')
        }
    }
})

此外,如果想响应式的操作state中的属性,可以这样写:
1、给state中新增age属性,在mutations写Vue.set(state,"age",11)
2、删除刚才新增的state属性则使用Vue.delete(state,'age') 具体代码实现如上所示。

三、actions

actions是操作行为处理模块。\color{red}{actions是操作行为处理模块。}负责处理vue组件接收到的所有行为交互(包含异步/同步操作),支持多个同名方法,按照注册的顺序依次触发, 向后台api的请求操作就在这个模块中进行,包括触发其他action以及提交mutations的操作,该模块也提供了Promise的封装,以支持其他action的链式触发。简而言之,actions方法就是用来专门进行异步操作,最终提交mutation的。

actions使用方法:

actions中的方法有两个默认参数(context,payload) 比如,在3s后才执行上文中的edit方法,这个时候就需要使用setTimeout,又因为setTimeout是异步的方法,所以需要在action中触发上文中的edit方法,
写法如下: store.js

const store = new Vuex.store({
    state:{
        name:'hello'
    },
    mutations:{
        edit(state,payload){
            state.name = payload//这一步就把state中name的值改为了张三
        },
        add(state){
        	Vue.set(state,'age',11)
        }
        delete(state){
        	Vue.set(state,'age')
        }
    },
    actions:{
    	editEmit(context,payload){
          setTimeout(()=>{context.commit('edit',payload)},3000)
        }
       // 因为是异步的,所以可以封装一个Promise对象
        //editEmit(context,payload){
        	//return new Promise((resolve,reject)=>{
            	// setTimeout(()=>{
                // context.commit('edit',payload)
                // resolve()
                // },3000)
            //})
        //}
    }
})

在App.vue中就不是触发mutation了而是触发action:

this.$store.dispatch('editEmit','张三')

修改成promise写法之后,这样用:

this.$store.dispatch('editEmit','张三').then(()=>{
//...
})

在另一个action中也可以这样写:

actions: {
  // ...
  editEmit_1 ({ dispatch, commit }) {
    return dispatch('editEmit').then(() => {
      commit('someOtherMutation')
    })
  }
}

四、getters

读取state对象的方法。\color{red}{读取state对象的方法。}vue通过该方法读取全局的state对象。

getters使用方法:

Getters中的方法有两个默认参数
state: 当前VueX对象中的状态对象
getters: 当前getters对象,用于将getters下的其他getter拿来用

store.js中

const store = new Vuex.store({
    state:{
        name:'hello'
    },
    mutations:{
        edit(state,payload){
            state.name = payload//这一步就把state中name的值改为了张三
        },
        add(state){
        	Vue.set(state,'age',11)
        }
        delete(state){
        	Vue.set(state,'age')
        }
    },
    getters:{
    	firstName(state){
           return "姓名"+state.name
        },
        fullName(state,getters){
          return getters.firstName+'age'+state.age
        }
    }
})

五、modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。

代码示例:

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
export default store

用法:

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

另外一种嵌套子模块的写法如下:

// menu.js

// initial state
const state = {
  isCollapse:false//控制伸缩动画是否展开
}
// getters
const getters = {
  isCollapseStatus: state => state.isCollapse
}
// actions
const actions = {
  checkout ({ commit},data) {
     commit('toggleCollapse',data)
  }
}
// mutations
const mutations = {
  toggleCollapse (state, data) {
  	state.isCollapse = data
  }
}

在store.js中引入:

import Vuex from 'vuex'
import products from './modules/menus' //引入子模块
Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    menus   // 添加进模块中
  }
})

总结:
vuex的组件接收交互行为,可以概括为调用dispatch方法触发action相关处理,若页面需要改变,则调用commit方法提交mutations来修改state,通过getters获取到state的新值,重新渲染vue组件,界面随之更新。