vuex使用小计

1. 安装vuex

npm install vuex --save

2. 引入vuex

import Vuex from 'vuex'

3. 文件安装

Vue.use(Vuex)

4. 实例化

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment: state => state.count++
  }
})

5. 挂载注入(此处为全局注入)

new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

6. 组件使用

状态读取:store中的状态应该从组件的计算属性中去读取,因为状态存储是响应式的。对于一个组件需要获取较多的状态的时候,可以在计算属性中引入 mapState 辅助函数去计算,作用不大…也就少写几个字。

computed: {
  count () {
    return this.$store.state.count
  }
}

7. getters使用

getters相当于计算属性computed,当依赖发生改变时才会刷新对应的缓存值。Getters 接受 state 作为其第一个参数,另一个getter作为第二个参数。也有一个 mapGetters 函数可以简化书写。

const store = new Vuex.Store({
  state: {
    arr: [{
      value: 'first',
      state: true
    }, {
      value: 'second',
      state: false
    }, {
      value: 'third',
      state: true
    }]
  },
  getters: {
    trueArr: state => {
      return state.arr.filter(item => item.state)
    }
  }
})
// 组件中:
computed: {
    arr() {
      // [{value: 'first', state: true}, {value: 'third', state: true}]
      return this.$store.getters.trueArr
    }
  }

8. Mutations状态改变

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutations 非常类似于事件:每个 mutation 都有一个字符串的 事件类型(事件名) (type) 和 一个 回调函数(处理函数) (handler)。
当然,你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload),在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment(state, params) {
        state.count += params.n
    }
  }
})
// 组件中触发事件:
methods: {
    addCount() {
      this.$store.commit('increment', {
        n: 2
      })
    }
}

提交 mutation 的另一种方式是直接使用包含 type 属性的对象,当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此 handler 保持不变:

store.commit({
  type: 'increment',
  n: 2
})

注意事项

  1. 最好提前在你的 store 中初始化好所有所需属性。
  2. 当需要在对象上添加新属性时,你应该使用 Vue.set(obj, ‘newProp’, 123), 或者
    以新对象替换老对象。例如,利用 stage-3 的对象展开运算符我们可以这样写:
    state.obj = { …state.obj, newProp: 123 }。
  3. mutation 必须是同步函数。

9. Actions状态改变

Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment: state => state.count++
  },
  actions: {
    increment(context, paramsObj) {
      setTimeout(function(){
        context.commit('increment', paramsObj)
      }, 1000)
    }
  }
})
// 分发, 载荷部分同mutations
methods: {
    delayCount() {
      this.$store.dispatch('increment', 2)
    }
}

10. Modules

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
  }
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

THE END!