Vuex

Vuex借鉴了Flux和Redux设计思想.

优点:

    Vue组件父子之间通过$on、$emit自定义事件来进行通信

    Vuex可以解决同级组件之间无法传递消息

执行步骤

Store: 数据仓库,包含state对象,组件通过getter从store读取数据,通过Getter

核心模块:

    1、state: 定义存储状态

    2、getter: 对数据进行过滤,获取state数据,在计算属性中获取state的值

    3、mutation: 同步操作,更改 Vuex 的 store 中的state值的唯一方法是提交 mutation

    4、action: 异步操作,Action通过commit()方法来调用mutation中的方法在改变来改变state的值,而不是直接改变state中的值

            分发Action: store.dispatch()方法触发

    5、modules: 如果应用过大,便可以使用 modules 来分割管理,不至于 store 变得非常臃肿


    调用同步的mutation  this.$store.commit('mutationName')

    调用异步的Action    this.$store.dispatch('mutationName')

        export default {
            insertMessage({commit}, insertData){
                fetch('/login',{
                    username,
                    password
                })
                .then((res)=>{
                    return res.json();
                })
                .then((res) => {
                    // 调用mutation
                    commit('insertMessage', res.data);
                })
            }
        }

State

用来存储数据,如果在组件中获取state中的数据,可以通过两种方法来获取: 计算属性computed 和 Getters

getter

在组件中用来获取Store中state,通过getter获取,组件中在通过computed来调用getter

getters.js
export const sideData = (state) => {
    return state.sideData;
} 

<template>
    <div class="box">
        {{ getSideData }}
    </div>
</template>

// 方法1: computed
computed: {
    getSideData () {
        return this.$store.state.sideData;            // 当getSideData的值改变就会显示出来
    }
}


// 方法2: mapState函数获取
import { mapState } from 'vuex';        // 引用mapState()
export default {
    name: 'side',
    computed: {
        ...mapState({    // 对象展开运算符
            getSideData: (state) => {
                return state.sideData
            }
        })
    }
}

Mutations

用来更改Store中state的数据,它是同步的

1、commit()触发Action, 之后Action触发mutation来改变state的值

    // 定义mutations 
    export default {
        changeSideData(state, sideJson){
            state.sideData.push(sideJson)
        }
    }

    // 触发
    methods:{
        addSideData(){
            let side = {
                id: 1,
                name: this.name,
                introduce: this.introduce
            }
            this.$store.commit('changeSideData', side);
        }
    }

2、使用mapMutations() 来定义改变

Actions

actions提交到 Mutations中,action而不能直接改变state的值

actions可以包含异步操作,mutations是同步的

// 定义action
export const holderSilde = ({commit}, {name, introduce}) => {    
    // {name, introduce} 这里注意一定对象传过来,这里为解析赋值写法,函数不接收第三个参数
    var side = {
        id: 1,
        name: name,
        introduce: introduce
    }
    commit('changeSideData', side)
}


// 调用 分发dispatch
methods:{
    addSideData(){
        // 第二个为传过去的参数
        this.$store.dispatch('holderSilde', {name: this.name, introduce: this.introduce});
    }
}

Modules

Vuex可以将Store分割到各模块,每个模块都有自己的store、mutations、actions、getters

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

示例

// store.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations.js';
import actions from './actions.js';
import getters from './getters.js';
Vue.use(Vuex);

// 初始化数据
const state = {
    currentId: 0,
    currentUsername: '',
    sideData: [
        {
            id: '1',
            username: 'siguang',
            introduce: '用户描述'
        },
        {
            id: '2',
            username: 'lulu',
            introduce: '用户描述'
        }
    ]
}

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


// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store.js'
Vue.config.productionTip = false;

let vm = new Vue({
    el: '#app',
    router,
    store,
    components: { App },
    template: '<App/>'
})

window.vm = vm;

| https://vuex.vuejs.org/zh