每天学习一点点 - vuex

最近比较闲,抽时间过了一遍vuex的文档。同时写了官网上购物车的那个小demo。下面来总结一下一些vuex的一些知识点

一.vuex是什么?

官方文档上写:vuex是一个专为vue.js应用程序开发的状态管理模式。这个状态自管理应用包括以下几个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将state映射到视图;
  • actions,响应在view上的用户输入导致的状态变化。

二.vuex的核心

vuex应用的核心就是store(仓库)。"store"基本上就是一个容器,它包含着你的应用中大部分的状态(state)。

  • vuex的状态是响应式的。即:若store中state发生改变,组件会随之更新。
  • 你不能直接修改state,而是使用commit显示地提交mutation。

每天学习一点点 - vuex

三.State

在vue组件中获取状态

// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

使用mapState辅助函数
在一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些复杂。为了解决这个问题,可以使用mapState辅助函数

// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default { 
  computed: mapState({
    count: state => state.count,
    // 传入字符串'count'等同于'state => state.count'
    countAlias: 'count',
    // 使用模块并且对应模块名称为cart时,获取cart里面对应的count属性
    count: state => state.cart.count
  })
}

当计算属性的名称与state子节点名称相同时,可以给mapState传入一个字符串数组

computed: mapState([
    'count'
])

对象展开运算符...mapState

computed: {
  localComputed() {
    ...mapState({

    })
  }
}

四.Getter

从store中的state派生出一些状态。可以理解为store的计算属性。当getter所依赖的值发生改变时,getter的值会随之改变。

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}

如果你想将一个 getter 属性另取一个名字,使用对象形式:

mapGetters({
  // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})

模块化状态下,getter取值

// 模块为cart
computed: {
  ...mapGetters('cart', {
    doneCount: 'doneTodosCount'
  })
}

五.Mutation

更改vuex的store中的状态的唯一办法是提交mutation
注意:

mutation必须是同步函数,异步需要放在aciton中
const store = new Vuex.store({
  state: {
    count:1
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})
store.commit('increment')

提交载荷(Payload)
你可以向store.commit传入额外的参数,即mutaition的荷载(payload)

mutations: {
  increment(state, n) {
    state.count += n
  }
}

store.commit('increment', 10)

在组件中提交mutation

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`

      // `mapMutations` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}

六.Action

Action类似于mutation。不同在于:

  • Action提交的是mutation,而不是直接改变状态。
  • Action可以包含异步操作
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
    // 或者也可以用es2015的解构赋值写成下面这种形式
    increment({ commit }) {

    }
  }
})

分发Action
Action通过store.dispatch方法触发

store.dispatch('increment')

在组件中分发Action

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

七.Module

Vuex允许我们将store分割成模块。

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 的状态

默认情况下,模块内部的action、mutation和getter是注册在全局命名空间的。如果你希望你的模块具有更高的封装度和复用度,你可以通过添加namespaced:true的方式使其成为带命名空间的模块。在模块被注册后,它所有getter、action及mutation都会自动根据模块注册的路径调整命名。

const store = new Vuex.Store({
  modules: {
    account: {
      namespaced: true,
      state: {},
      getters: {
        isAdimin() {...} // getters['account/isAdmin']
      }
    }
  }
})

对于内部模块,如果你希望获取全局的state和getter,可以通过rootState、rootGetter获取到
若需要在全局命名空间内分发action或者提交mutation,将{root: true}作为第三个参数传给dispatch或者commit即可

// 在另外一个模块获取cart模块
rootState.cart.all
dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
commit('someMutation', null, { root: true }) // -> 'someMutation'

相关推荐