vue

vuex基础

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

Posted by page on September 16, 2020

vuex

一个专为vue.js应用程序开发的状态管理模式,它采用集中式存储来管理多个组件间共享的状态

安装

npm install vuex --save

使用准备

项目 store 下新建 index.js

// /store/index.js
// 引入插件
import Vuex from 'vuex'
import Vue from 'vue'
// 使用插件
Vue.use(Vuex);

// 添加vuex参数
export default new Vuex.Store({
  state: {...},
  mutations: {...},
  actions: {...},
  getters: {...},
  modules: {...}
});

main.js 使用store实例

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

核心概念

state

$store.state ——访问共享状态

单一状态树:

即单一数据源,意味着每个vue.js应用将仅仅包含一个store实例,让我们能够直接地定位任意状态

getter

$store.getters ——计算属性

  • 简单计算值

    // 1. 添加state计算值
    getters: {
      dbCounter(state){
        return state.counter * 2
      },
      maleStudents(state){
        return state.students.filter(v => v.gender === "")
      }
    }
    // 2. 访问getter的计算属性
    // <div></div>
    // <div></div>
    
  • 对getter计算值

    getter: {
        maleStudentLength(state, getters){    //第2个计算参数为store的getter计算值
            return getters.maleStudents.length
        }
    }
    
  • 向getter传参

    filterStudents: state => filterOption => state.students.filter((v) => {
      for(let k in filterOption){
        if(filterOption[k] !== v[k]) {
          return false
          break;
        }
      };
      return true
    })
      
    // 使用:
    // <div>
      // 向计算属性返回函数传参
      // $store.getters.filterStudents({gender: "女",age: 20})
    // </div>
    

mutations

$store.commit('mutation') ——更新状态

  1. 声明事件类型及回调函数

    mutations: {
        increment(state){
            state.count++
        },
        decrement(state){
            state.count--
        }
    }
    
  2. commit 提交状态更新

    methods: {
      addition(){
        this.$store.commit('increment');
      },
      subtraction(){
        this.$store.commit('decrement');
      }
    }
    
  3. mutations 传递参数( payload 负荷)

    // 接收参数更新状态
    mutations: {
      addStudent(state, student){    // 声明事件类型与回调函数
        state.students.push(student);
        this.commit('updateCount');  // 内部this指向$store,可访问getters,调用commit
      }
    }
    // 提交事件与参数
    addStudent(){
      this.$store.commit('addStudent',{name: 'ym',age: 20,gender: ""})
    }
       
    // 附:payLoad提交风格
    mutations: {
      addStudent(state, student){    //声明事件类型与回调函数
        state.students.push(student);
      }
    }
    // 提交事件与payLoad对象
    addStudent(){
      this.$store.commit({type: 'addStudent',{ name: 'ym'... } }) //传参payLoad对象
    }
    

actions

$store.dispatch('actions') ——异步更新状态

mutations 中的异步更新状态处理是无法捕捉的,应该在 actions 中开启异步处理后再中转至 mutatios 事件类型

Promise形式

// store
actions: {
  UpdateStudent(context, payLoad){
    return new Promise((resolve, reject) => {    // 返回Promise实例至调用处
      setTimeout(() => {
        context.commit('updateStudent',payLoad);
        resolve(payLoad);
      },3000)
    })
  }
}

// example
updateName(){   // 调用actions转发回调后,为返回的Promise添加then代码
  this.$store.dispatch('aUpdateStudent', 'pagge').then(data => {
    console.log("异步更新状态成功!");
    console.log("回调的信息", data);
  });
}

回调函数形式

// store
actions: {
  UpdateStudent({ commit }, payLoad){
    setTimeout(() => {
      commit('updateStudent', payLoad.options);
      payLoad.success(payLoad.options);   // 执行参数的异步回调
    })
  }
}

// example
updateName(){
    this.$store.dispatch('aUpdateStudent', { // 传递对象类型的payLoad
      options: 'pagge',
      success(data){    // 参数中包含异步回调函数
        console.log("异步更新状态成功!");
        console.log("回调的信息", data);
      }
    })
  }

modules

每个模块拥有自己的state、mutations、actions、getters

modules下声明局部状态对象

const moduleA = {
  state: {
    id: "201710622109",
    grade: "2017级"
  }
}
modules: {
  moduleA
}
  • $store.state.moduleA.stateB 访问局部状态对象的state状态值

  • $store.getters['moduleA/getterB'] 访问getters计算属性值

    不允许全局和局部getters命名重复,否则报错;解决:namespaced: true(命名空间)

  • $store.commit('moduleA/mutationB') 更新局部状态state值

  • $store.dispatch('moduleA/actionB')

    actionB(context){
        // context指向局部store的状态树
        ......
        // 提交事件类型自局部状态向全局查找对应事件
        context.commit('updateGrade');
        // 调用另一module状态
        context.commit('modules/mutation', payload, { root: true })
    }
    
  • rootState, rootGetters 参数访问根状态

    getterA(state, getters, rootState, rootGetters) { ... }
    actionA({state, getters, rootState, rootGetters, commit, dispatch}) { ... }
    

Map辅助函数

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';

......
computed: {
    ...mapState(['stateA']),
    // 要求user模块 namespaced: true
    ...mapGetters('user', ['userInfo', 'roleInfo'])
},
methods: {
    ...mapMutations('user', { updateInfo: 'SET_USER_INFO' }),
    ...mapActions('user', ['login'])
}
// 创建基于某个命名空间辅助函数
const { mapState, mapActions } = createNamespacedHelpers('user');

......
computed: {
    ...mapGetters(['userInfo', 'roleInfo'])
},
methods: {
    ...mapMutations({ updateInfo: 'SET_USER_INFO' }),
    ...mapActions(['login'])
}

store目录

/store
    index.js                              包含use(Vuex),Vuex.store实例创建,全局state状态管理
    /modules                              局部状态管理模块
        moduleA
        ...

// 全局过多,可再分离
    getters.js                            全局状态计算值
    mutations.js                          全局状态更新时间类型
    actions.js                            全局state异步状态更新处理