Open Twlig opened 2 years ago
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
而Vuex 可以帮助我们管理共享状态。
Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
const store = createStore({ state: { count: 10 } })
Vuex 通过 Vue 的插件系统将 store 实例从根组件中“注入”到所有的子组件里。且子组件能通过 this.$store 访问到。
this.$store
// 创建一个 Counter 组件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return this.$store.state.count } } }
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性.
mapState
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from 'vuex' export default { // ... computed: // 使用对象展开运算符将此对象混入到外部对象中 ...mapState({ // 箭头函数可使代码更简练 count: state => state.count, //... }) }
获取从 store 中的 state 中派生出的状态。
const store = createStore({ state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: (state) => { return state.todos.filter(todo => todo.done) }, doneTodosCount (state, getters) {//Getter 也可以接受其他 getter 作为第二个参数 return getters.doneTodos.length }, getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } } })
computed: { doneTodosCount () { return this.$store.getters.doneTodosCount } }
getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的。
this.$store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
mapGetters
import { mapGetters } from 'vuex' export default { // ... computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 ...mapGetters([ 'doneTodosCount', newDoneCount: 'doneTodosCount' //取新名字 // ... ]) } }
用于更改 Vuex 的 store 中的状态。mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)\和一个**回调函数 (handler)**。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = createStore({ state: { count: 1 }, mutations: { increment (state, n) { // 变更状态 state.count += n } } })
不能直接调用一个 mutation 处理函数。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation 处理函数,你需要以相应的 type 调用 store.commit 方法:
increment
//1.方法1 this.$store.commit('increment', 10) //2.方法2 this.$store.commit('increment', { num: 10 }) //3.方法3 this.$store.commit({ type: 'increment', num: 10 })
注意: mutation 必须是同步函数
Action 类似于 mutation,不同在于:
const store = createStore({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { //context与 store 实例具有相同方法和属性 context.commit('increment') } } })
Action 通过 store.dispatch 方法触发。
store.dispatch
this.$store.dispatch('increment')
action中返回Promise对象
actions: { actionA ({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { commit('someMutation') resolve() }, 1000) }) }, actionB ({ dispatch, commit }) { return dispatch('actionA').then(() => { commit('someOtherMutation') }) } }
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... } } const store = createStore({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态
Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
而Vuex 可以帮助我们管理共享状态。
Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
State
组件获取state
this.$store
Vuex 通过 Vue 的插件系统将 store 实例从根组件中“注入”到所有的子组件里。且子组件能通过
this.$store
访问到。mapState 辅助函数
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用
mapState
辅助函数帮助我们生成计算属性.Getter
获取从 store 中的 state 中派生出的状态。
组件获取getter
通过属性访问
getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的。
通过方法访问
getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
mapGetters 辅助函数
mapGetters
辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:Mutation
用于更改 Vuex 的 store 中的状态。mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)\和一个**回调函数 (handler)**。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
不能直接调用一个 mutation 处理函数。这个选项更像是事件注册:“当触发一个类型为
increment
的 mutation 时,调用此函数。”要唤醒一个 mutation 处理函数,你需要以相应的 type 调用 store.commit 方法:注意: mutation 必须是同步函数
Action
Action 类似于 mutation,不同在于:
分发Action
Action 通过
store.dispatch
方法触发。组合Action
action中返回Promise对象
Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割: