Vuex核心概念

状态管理模式
Vuex和redux是一个状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex: 官方文档
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
Vuex 和单纯的全局对象有以下两点不同:

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

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

Vuex核心概念_第1张图片
vuex.png

使用

  1. State
  • 一般在Vue组件中在计算属性computed中返回一个某个状态
// 创建一个 Counter 组件
const Counter = {
  template: `
{{ count }}
`, computed: { count () { return store.state.count } } }
  • mapState辅助函数来获取多个状态,mapState接受{}或[]作为参数。{}为键值对形式,key:value,key为计算属性,value 为函数,参数为store.state, 返回需要的state;当映射的计算属性的名称与 state 的子节点名称相同时,可以给 mapState 传一个字符串数组
// 1
 computed: mapState({
    // 箭头函数可使代码更简练
    count: state => state.count,

    // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',

    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
  
  // 2
  computed: mapState([
  // 映射 this.count 为 store.state.count
  'count'
])
  • mapState 与计算属性混用时候,需要用到 ... 展开符将多个对象合并成一个传给 computed 属性
computed: {
  localComputed () { /* ... */ },
  // 使用对象展开运算符将此对象混入到外部对象中
  ...mapState({
    // ...
  })
}
  1. Getter
    Getter 可以认为是 store 的计算属性, getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})
  • 访问方式
1. 属性:
// Getter 也可以接受其他 getter 作为第二个参数:
getters: {
  // ...
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}
// 使用
computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}
2. 方法
// 你也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
};

store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
  • mapGetter
computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
  
  mapGetters({
  // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})
  1. mutation
    更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state, n) {
        state.count += n
    }
  }
})
// 使用
store.commit({
  type: 'increment',
  amount: 10
})
  1. action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state,paload) {
      state.count = state.count + paload.amount
    }
  },
  actions: {
    increment (context,paload) {
      context.commit('increment',paload)
    }
  }
})

// 分发store
// 以载荷形式分发
store.dispatch('incrementAsync', {
  amount: 10
})

// 以对象形式分发
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

异步 Action
// 假设 getData() 和 getOtherData() 返回的是 Promise

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

你可能感兴趣的:(Vuex核心概念)