Vuex

作者: 指尖轻敲 | 来源:发表于2019-02-12 15:28 被阅读22次

    安装配置

    npm install vuex --save
    

    我使用的vue-cli脚手架(不再强调),在main.js中引入并且配置到全局

    import Vuex from 'vuex';
    import storeConfig from './config/store.js';
    Vue.use(Vuex);
    const store = new Vuex.Store(storeConfig);
    new Vue({
      store,
      render: h => h(App)
    }).$mount('#app');
    

    核心概念

    那么我就看一下store.js有哪些内容吧:

    const storeConfig = {
        state: {
            data: [],
        },
    };
    export default storeConfig;
    
    1. state

    就是全局数据,在所有组件中都可以获取到。这个没什么多说的。
    在组件中如果要获取store中的state,可以通过两种方法:首先第一就是直接访问

    this.$store.state.data
    

    可以看出,如果某个子组件中要多次使用store中的数据,那么这样写起来会很啰嗦的,我们可以使用mapState辅助函数来减少敲键盘的次数。

    该函数返回一个对象,如果映射的计算属性名称和state中的名称相同,可以直接传入一个数组。

    import { mapState } from 'vuex'
    export default {
        computed: {
            ...mapState(['data',])
        }
    }
    

    如果要对属性进行重命名,可以传入一个对象。使用的时候直接使用心得名称即可。

    ...mapState({
        myData: 'data'
    })
    
    2. getters

    有时我们需要获取state中的数据进行处理之后的数据,比如筛选之类的。并且这个处理之后的数据要在多个组件中使用,每个组件都写处理方法肯定不是我们想要的,这时getter就很有用了。

    const storeConfig = {
        state: {
            data: [],
        },
        getters: {
            getList: (state, getters) => {
              return state.data.filter(item=> item.id !== 0)
            }
        }
    };
    

    这样就可以直接从getters中获取处理过的数据,而且这个值是会被缓存的,如果计算的依赖不变化是不会重新计算的,减少了不必要的消耗。第二个参数表示getter也接受其他getter。

    在组件中要获取getter也是非常简单的,有以下三种方法:
    第一种,直接通过Getter暴露的对象访问,

    this.$store.getters.getList
    

    第二种,如果getter的返回值是一个函数,我们可以通过调用方法的形式访问,

    getters: {
      getTodoById: (state) => (id) => {
        return state.todos.find(todo => todo.id === id)
      }
    }
    
    this.$store.getters.getTodoById(5)
    

    第三种,通过辅助函数mapGetters访问,使用方法和mapState基本一致,可以接受一个数组,也可以接受一个对象来重命名。

    import { mapGetters } from 'vuex'
    export default {
        computed: {
            ...mapGetters(['getList',])
        }
    }
    
    3. mutations

    state中的数据是不能随便修改的,只能通过提交mutation修改,

    const storeConfig = {
        state: {
            count: 1
        },
        mutations: {
            increment (state, n) {
              state.count = state.count + n;
            }
        }
    };
    

    提交时可以通过commit方法来提交,接受第二个参数作为要传给mutation的参数。这个参数可以是一个单一的值,大多数情况下我们需要的是一个对象。

    this.$store.commit("increment", 10);
    

    也可以通过mapMutations辅助函数提交,合并到methods中,直接当方法调用即可。

    import { mapMutations } from "vuex";
    export default{
        methods: {
            ...mapMutations(['increment '])
        },
        mounted(){
            this.increment({num: 10});
        }
    }
    

    补充:

    1. 使用常量代替mutation事件类型。这样我们可以把所有的mutation提取到一个文件中单独管理

    mutationTypes.js

    export const CHANGEDATA= 'CHANGEDATA'
    
    import { CHANGEDATA} from 'mutationTypes.js'
    //...
    mutations:{
        [CHANGEDATA](state){
            ...
        } 
    }
    // ...
    
    1. mutation必须是同步的,如果要想异步调用请看下面的actions
    4. actions

    actions其实就是给提交mutation添加了一个中间环节,通过先分发Action,然后再action中提交mutation。重要的是action中没有同步的限制。

    这里直接复制官网的一段代码,懒得敲了,

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('increment')
        }
      }
    })
    

    action函数接受一个context参数,这个参数和store实例一样,因此可以调用context.commit,也可以通过它调用state或者getters等等。

    我们可以使用ES6的参数结构来简化代码。

    actions: {
      increment ({ commit }) {
        commit('increment')
      }
    }
    

    接下来怎么分发action呢?同样的,可以直接调用dispatch方法分发,

    this.$store.dispatch("increment");
    

    也可以使用辅助函数mapActions来分发。使用方法和之前的辅助函数都一样,不废话了。

    import { mapActions } from 'vuex'
    export default {
      methods: {
        ...mapActions(['increment']),
        ...mapActions({
          add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
        })
      }
    }
    

    相关文章

      网友评论

          本文标题:Vuex

          本文链接:https://www.haomeiwen.com/subject/ociheqtx.html