Vue(三):Vuex

92 阅读3分钟

使用

1. 安装 vuex 安装包

npm install vuex --save

2. 创建 store.js

main.js 平级,新建 sotre.js 文件

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
    },
    mutations: {
    },
    actions: {
    }
})

3. 将 store 对象挂载到 vue 实例中

// main.js 
import store from './stroe'
new Vue({
    el: '#app', // 指定要控制的区域
    render: h => h(app), // 渲染app根组件
    router, // 挂载路由
    // 将创建的共享数据对象,挂载到vue实例中
    // 所有的组件,就可以直接从sotre中获取全局数据了
    store
})

Vuex 的核心概念

State

State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储

const store = new Vuex.Store({
    state: {
        count: 0 // 定义一个全局count
    },
    mutations: {
    },
    actions: {
    }
})

组件中访问 State 中数据的第一种方式

// this.$sotre.state.全局数据名称
this.$sotre.state.count

组件中访问 State 中数据的第二种方式

// 1. 从vuex中按需导入mapState函数
impotr { mapState } from 'vuex'

通过刚才导入的 mapState 函数,将当前组件需要的全局数据,映射为当前组件的 computed 计算属性:

// 2. 将全局数据,映射为当前组件的计算属性
computed: {
    ...mapState(['count'])
}
// 此时 count 就是当前组件中的一个属性,直接 this.count 就能获取到

Mutation

Mutation 用于变更 Store 中的数据

  1. 只能通过 mutation 变更 Store 数据,不可以直接操作 Sotre 中的数据
  2. 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化

定义 Mutation

const store = new Vuex.Store({
    state: {
        count: 0 // 定义一个全局 count
    },
    mutations: {
        add(state) {
            // 变更状态
            state.count ++
        }
    },
    actions: {
    }
})

触发 mutations 的第一种方式

// 组件中使用 mutation
methods: {
    handler() {
        // commit 的作用就是调用某个mutation函数
        this.$sotre.commit('add')
    }
}

Mutation 传参

const store = new Vuex.Store({
    state: {
        count: 0 // 定义一个全局 count
    },
    mutations: {
        add(state) {
            // 变更状态
            state.count ++
        },
        addN(state, step) {
            // 变更状态
            state.count += step
        }
    },
    actions: {
    }
})
methods: {
    handler() {
        this.$sotre.commit('addN', 3)
    }
}

触发 mutations 的第二种方式

// 1. 从 vuex 中按需导入 mapMutations 函数
impotr { mapMutations } from 'vuex'

通过刚才导入的 mapMutations 函数,将需要的 mutations 函数,映射为当前组件的 methods 方法:

// 2. 将指定的 mutations 函数,映射为当前组件的 methods 函数
methods: {
    ...mapMutations(['add', 'addN']),
    handler1() {
        this.add()
    },
    handler2() {
        this.addN(3)
    }
}

注意:mutations 函数中不能写异步代码

const store = new Vuex.Store({
    state: {
        count: 0 // 定义一个全局 count
    },
    mutations: {
        add(state) {
            /* 不要这么写
            setTimeout(() => {
                    state.count ++
            }, 1000)
            */
        }
    },
    actions: {
    }
})

Action

Action 用于处理异步任务。

如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action中 还是要通过触发 Mutation 的方式间接变更数据。

const store = new Vuex.Store({
    state: {
        count: 0 // 定义一个全局 count
    },
    // 只有 mutations 中定义的函数,才有权力修改 state 中的数据
    mutations: {
        add(state) {
            // 变更状态
            state.count ++
        },
        addN(state, step) {
            // 变更状态
            state.count += step
        }
    },
    actions: {
        addAsync(context) {
            setTimeout(() => {
                // 在 actions 中,不能直接修改 state 中的数据
                // 必须通过 context.commit() 触发某个 mutation 才行
                context.commit('add')
            }, 1000)
        }
    }
})

触发 actions 的第一种方式

methods: {
    handler() {
        this.$store.dispatch('addAsync')
    }
}

Action 传参

const store = new Vuex.Store({
    state: {
        count: 0 // 定义一个全局 count
    },
    // 只有 mutations 中定义的函数,才有权力修改 state 中的数据
    mutations: {
        add(state) {
            // 变更状态
            state.count ++
        },
        addN(state, step) {
            // 变更状态
            state.count += step
        }
    },
    actions: {
        addAsync(context) {
            setTimeout(() => {
                // 在 actions 中,不能直接修改 state 中的数据
                // 必须通过 context.commit() 触发某个 mutation 才行
                context.commit('add')
            }, 1000)
        },
        addNAsync(context, step) {
            setTimeout(() => {
                context.commit('addN', step)
            }, 1000)
        }
    }
})
methods: {
    handler() {
        this.$store.dispatch('addNAsync', 5)
    }
}

触发 actions 的第二种方式

// 1. 从 vuex 中按需导入 maoActions函数
import { mapActions } from 'vuex'

通过刚才导入的 mapActions 函数,将需要的 actions 函数,映射为档期组件的 methods 方法

// 2. 将指定的 actions 函数,映射为当前组件的 methods 函数
methods: {
    ...mapActions(['addAdync', 'addNAsync'])

    handler1() {
        this.addAdync()
    }

    // 也可以直接将它作为方法
    addNAdync() {}
}

注意:mutation 和 action 至多只能传一个参数,如果需要传递多个参数可以包装成对象后再传。

Getter

Getter 用于对 Store 中的数据进行加工处理形成新的数据。

  1. Getter 可以对 Store 中已有的数据加工处理之后形成新的数据,类似 Vue 的计算属性。
  2. Store 中的数据发生变化,Getter 的数据也会跟着变化。
// 定义 Getter
const store = new Vuex.Store({
    state: {
        count: 0
    },
    mutations: { ... },
    actions: { ... },
    getters: {
        // 写法1
        showNum: state => {
            return '当前最新的数量是【' + state.count + '】'
        }
        // 写法2
        showNum(state) {
            return '当前最新的数量是【' + state.count + '】'
        }
    }
})

使用 getters 的第一种方式

this.$store.getters.名称

使用 getters 的第二种方式

import { mapGetters } from 'vuex'

computed: {
    ...mapGetters(['showNum'])
}

视频地址