blog icon indicating copy to clipboard operation
blog copied to clipboard

Vuex学习笔记

Open pb-cheung opened this issue 8 years ago • 0 comments

Vuex官方中文文档

文档核心内容提炼。

Vuex是一个状态管理模式

State

Vuex使用单一状态树,用一个对象包含了全部的应用层级状态。

Getters

Vuex允许我们在store中定义【getters】(可以认为是store的计算属性)。Getters接受state作为其第一个参数:

const store = new Vuex.Store({
    state: {
        ...
     },
    getters: {
        doneTodos: (state) = > {
            return state.todos.filter(todo => todo.done);
       }
   }
});

Getters会暴露为store.getters对象:

store.getters.doneTodos

有些类方法和计算属性结合的意思。多个组件需要使用某个计算属性(某个state)的时候,把它抽取到一个出来放到store中就是所谓的getter

Mutations

更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutations非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数>(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数。

Mutations有点像注册了一堆事件处理函数的集合。可类比Redux中的Reducer。

Actions

Action类似于mutation,不同在于:

  • Action 提交的是mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

例子:

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

Action通过store.dispatch方法触发:

store.dispatch("increment")

实际的操作动作都是在Action中完成的,包括常见的发起Ajax等异步操作,然后再提交(commit)mutation而非省略action直接提交mutation的原因是mutation必须同步执行。即,Mutation扭转状态,Action中执行具体操作。

Modules

使用单一的状态树,导致应用的所有状态集中到一个很大的对象。但是,当应用变得很大时,store对象会变得臃肿不堪。

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

const moduleA = {
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
};
const moduleB = {
    state: { ... },
    mutations: { ... },
    actions: { ... }
};
const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
     }
});
store.state.a        //    moduleA的状态
store.state.b        //    moduleB的状态

几个常用辅助函数

1.mapState

当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用mapState辅助函数帮助我们生成计算属性,让你少按几次键:

import { mapState } from "vuex";
export default {
    
}

2. mapActions

在组件中分发Action

你在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions辅助函数将组件的methods映射为store.dispatch调用(需要现在根节点注入store):

import { mapActions } from "vuex";

export default {
    ...
    methods: {
       ... 
       mapActions([
            "increment"        //映射 this.incement() 为 this.$store.dispatch("increment")
       ]),
        mapActions([
            add: "increment"    //映射this.add() 为 this.$store.dispatch("incement");
       ])
   }
}

3.

mapGetters辅助函数仅仅是将store中的getters映射到局部计算属性:

import { mapGetters } from "vuex"

export default {
    computed: {
        mapGetters([
            "doneTodosCount",
            "anotherGetter",
         ]);
     }
}

pb-cheung avatar Dec 11 '16 07:12 pb-cheung