vue - vuex

官网地址:https://vuex.vuejs.org/zh/guide/

每个【vuex】应用的核心 就是【store】(仓库)

【store】基本上就是一个容器,它包含着你的应用中大部分的【状态】(state)

Vuex 和单纯的全局对象的区别

  1. Vuex 的状态存储是响应式的。当Vue组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么对应的组件也会相应的得到高效更新。
  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径,就是显式的【提交】(commit)mutation,这样使得我们可以方便的跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好的了解我们的应用。

简单的 store

// 如果在模块化的构建系统中,请确保在开头调用 Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        increment(state) {
            state.count ++
        }
    }
})
// 触发状态变更
store.commit('increment')

// 读取状态
console.log(store.state.count)

Getter

可以认为是 store 的计算属性

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)
        }
        // 调用 store.getters.doneTodos

        // 传参
        getTodoById: state => id => {
            return state.todos.find(todo => todo.id === id)
        }
        // 调用
        // store.getter.getTodoById(2)
    }
})

辅助函数 mapGetters

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

import { mapGetters } from 'vuex'

export default {
    // ...
    computed: {
        // 使用对象展开符,将 getter 混入到 computed 计算属性中
        ...mapGetters([
            'doneTodosCount',
            'anotherGetter',
            // ...
        ])
        // 如果想将 getter 属性另取一个名
        ...mapGetters({
            // 把 this.doneCount 映射到 this.$store.getters.doneTodosCount
            doneCount: 'doneTodosCount'
        })
    }
}

Mutation(必须是同步函数)

更改 Vuex 的 store 中的状态的唯一方法是提交(commit)mutation

调用:store.commit(‘increment’)

const store = new Vuex.Store({
    state: {
        count: 1
    },
    mutation: {
        increment(state) {
            // 变更状态
            state.count ++
        }
    }
})

提交载荷(payload)

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

Action
类似于 mutation,不同点在于:

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

分发 Action

store.dispatch('increment')

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

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

在组件中分发【…mapActions】

组合 Action
store.dispatch 可以处理被触发的 action 的处理函数返回的Promise,并且 store.dispatch 仍旧返回 Promise

actions: {
    actionA ({ commit }) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                commit('someMutation')
                resolve()
            }, 1000)
        })
    }
}

分发 actionA

store.dispatch('actionA').then(() => {
    // ...
})

在另一个 action 中也可以调用

actions: {
    // ...
    actionB ({ commit, dispatch }) {
        return dispatch('ActionA').then(() => {
            commit('someOtherMutation')
        })
    }
}

Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象,使应用变得非常复杂,store对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块(从上到下进行同样方式的分割)

const moduleA = {
    state: { count: 0 },
    mutations: {
        increment(state) {
            // 这里 state 指模块的局部变量
            state.count ++
        }
    },
    actions: {
        // rootState 为根节点状态
        // state 为局部状态
        incrementOther({ state, commit, rootState }) {
            commit('increment')
        }
    },
    getters: {
        doubleCount (state) {
            return state.count * 2
        }
    }
}
const moduleB = {
    state: {...},
    mutations: {...},
    actions: {...}
}

const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
    }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

input 双向绑定的计算属性

使用带有 setter 的双向绑定的计算属性

<input v-model="message">
// ...
computed: {
    message: {
        get () {
            return this.$store.obj.message
        },
        set(value) {
            this.$store.commit('updateMessage', value)
        }
    }
}

猜你喜欢

转载自blog.csdn.net/M_wolf/article/details/81319854