Vuex的使用

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

应用场景

对于深层嵌套组件,依靠props进行父子组件的传递显得太过臃肿,并且难以维护。而vuex的出现就是为了解决数据传递的问题。Vuex做为一个全局管理仓库,能够管理全部组件的状态state,不一样组件之间也可依靠Vuex来共享状态State。ios

Vuex不一样于单纯的全局对象

1,Vuex的状态存储是响应式的。当Vue组件从store中读取状态时,若store的中的状态发生变化,那么相应的组件也会相应的获得高效更新。web

2,改变store中状态的惟一途径就是显式地提交mutation。全部的state的改变都必须通过mutation事件,方便咱们跟踪每个状态的的变化。vuex

核心概念

state

负责存储整个应用的状态数据。在vue组件中获取Vuex状态的方式以下,在计算属性中返回某个状态:vue-cli

1,须要在DOM节点上获取到状态;axios

实现:在项目中,在组件中把存在Vuex中的“columns”取出来,并显示在该组件上api

1),在computed中返回该状态。bash

computed: {
    columns(){
        return this.$store.state.columns;
    }
},
复制代码

2),在须要用到的dom节点上进行操做。框架

<el-col :span="20">
    <el-checkbox-group   v-model="column">
        <el-checkbox :label="item.name" v-for="(item,index) in columns" :key="index">{{item.name}}</el-checkbox>
    </el-checkbox-group>
</el-col>
复制代码

结果:每当store.state.columns变化时,都会从新计算属性,而且触发更新相关联的DOM。 2,在vue生命周期中获取到Vuex中的状态,能够直接用this.$store.state对象dom

eg:

this.id = this.$store.state.articleId;

mapState辅助函数

当一个组件须要获取多个状态时,vuex提供了mapState辅助函数生成计算属性。

实现:从Vuex中获取“activityLeft”和“columns”两个状态时,能够按如下两个方式获取。

1),直接获取

computed: {
  activityLeft(){
    return this.$store.state.activityLeft;
  },
  columns(){
    return this.$store.state.columns;
  }
}
复制代码

2),用mapState辅助函数辅助函数获取

computed: {
    ...mapState([
       'activityLeft',
       'columns'
    ])
 },
复制代码

mutation

上面说到,更改 Vuex 的 store 中的状态的惟一方法是提交 mutation。

Vuex 中的mutation很是相似于事件:每一个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。

实现:在组件中改变Vuex状态中的acticleId状态,不能够用“this.$store.state.articleId = 1”这种方式进行修改,须要如下面的方面进行修改。

eg:

1),组件中须要用state.commit来唤醒mutation中的handler。例如在点击编辑时,获取到该item的id传递给对应的handler

handleCurrentChange(id) {
   this.$store.commit("getArticleId",id);
 }
复制代码

2),在Vuex中添加一一对应的handler

mutations:{
   getArticleId(state,id){
     state.articleId = id;
   },  
}
复制代码

注意:

1,最好在提早在你的 store 中初始化好全部所需属性。上述例子应该在state中先初始化好articleId。

2,mutation必须是同步函数。在 mutation 中混合异步调用会致使你的程序很难调试,若是须要处理异步操做,可使用Action

Action

1,Action 提交的是 mutation,而不能直接变动状态

2,Action 能够包含任意异步操做

实现:在项目中,在Action中使用axios去获取数据,并把数据存进Vuex的状态里面。

1),在组件的methods中经过 store.dispatch 方法触发Action

handleSizeChange(val) {
  this.pageSize = val;
    let data = {
      "type":this.$store.state.navName,
      "wid":this.$store.state.websiteId,
      "pageSize":this.pageSize,
      "pageNum":this.pageNum,
      "searchTitle":this.searchTitle
     };
   this.$store.dispatch("getArticle",data);
},
复制代码

2),在Vuex注册一一对应的Action

actions:{
  getArticle({commit},{type='',searchTitle='',wid,pageNum=1,pageSize=20}){
    axios.post(api.url+'articleList',{
      type:type,
      searchTitle:searchTitle,
      wid:wid,
      pageSize:pageSize,
      pageNum:pageNum
    }).then((response)=>{
      if(response.data.ret == 0){
        var data = response.data;
        var msg = data.msg;
        var total = data.total;
        commit('getArticle',{msg,total})
      }
    });
  },
}
复制代码

3),经过提交 mutation 来记录状态变动

mutations:{
  getArticle(state,data){
    var res = data.msg;
    state.activityList = res;
    state.total = data.total;
  },
}
复制代码

重点:store.dispatch 能够处理被触发的 action 的处理函数返回的 Promise,而且 store.dispatch 仍旧返回 Promise:

eg:一个 store.dispatch 在不一样模块中能够触发多个 action 函数。

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}
复制代码

以上就是我在项目中基于vue-cli框架中使用Vuex的一些例子。最后上面提到的vuex状态附在下列store.js中。

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';
import api from '../api/api.js';
Vue.use(Vuex);
let store = new Vuex.Store({
  state:{
    columns:[],
    articleId:'',
  },
  mutations:{
    getArticle(state,data){
      var res = data.msg;
      state.activityList = res;
      state.total = data.total;
    },
    getArticleId(state,id){
      state.articleId = id;
    },
  },
  actions:{
    getArticle({commit},{type='',searchTitle='',wid,pageNum=1,pageSize=20}){
      axios.post(api.url+'articleList',{
        type:type,
        searchTitle:searchTitle,
        wid:wid,
        pageSize:pageSize,
        pageNum:pageNum
      }).then((response)=>{
        if(response.data.ret == 0){
          var data = response.data;
          var msg = data.msg;
          var total = data.total;
          commit('getArticle',{msg,total})
        }
      });
    },
  }    
});
export default store;
复制代码
相关文章
相关标签/搜索