Vuex简单学习

2018-11-02  本文已影响37人  阿清哪去了

一个Vue应用中,会使用到大量的组件,如果有些数据是全局的,比如说登录以后的用户信息,有很多组件会使用到用户信息,那么父组件,子组件,孙组件都用到用户的信息的情况下,我们通常需要使用参数传递的方式,通过props传参,一层层传递,若应用很复杂,这个代码的过程就需要很细致,代码也变得难以维护,一改全改。因此,我们采用Vuex来解决这个问题。将全局需要共享的数据,都保存在一个类似于单例对象中,存取十分方便。

简单示例(计数器demo)

const store = new Vuex.Store({
    // 存放全局状态
    state: {
        count: 0
    },
    // 对state中的数据的一个包装加工(类似于计算属性)
    getter: {

    },
    // 若要修改全局状态,一定要通过mutations来修改,若直接修改state对象,会造成特性的丢失
    mutations: {
        // 传入state参数对其进行操作
        increment (state) {
            state.count += 1; // 访问到state的count进行操作
        },
        decrement (state) {
            state.count -= 1;
        }
    },
    // 存放一些淡出的业务逻辑,不涉及页面行为
    actions: {

    }
})
new Vue({
    el: '#app',
    router,
    components: {App},
    template: '<App/>',
    store
})
<template>
    <div id="app">
        {{ count }}
        <router-view/>
    </div>
</template>

<script>
    import {mapState} from 'vuex'
    export default {
        name: "App",
        // 引入Vuex的mapState方法,放在计算属性中,传入一个数组,把要使用的state给映射进来
        // mapState返回一个类似于计算属性函数的数组,用...解构后平摊到computed中
        computed: {
            ...mapState(['count'])
        }
    }
</script>
<template>
    <div>
        <button @click="increase">增加</button>
        <button @click="decrease">减少</button>
    </div>
</template>

<script>
    import {mapMutations} from 'vuex'
    export default {
        name: "HelloWorld",
        // 同样的,我们用...解构,把对state的操作一一映射到methods中以便调用
        methods: {
            ...mapMutations(['increment', 'decrement']),
            // 这里用方法调用映射出来的操作
            increase () {
                this.$stroe.commit('increment')
            },
            decrease () {
                this.$stroe.commit('decrement')
            }
        }
    }
</script>

这个时候,点击按钮,就会对count数字进行加减的修改,这个时候打开Vue-devtool插件,可以看到具体的修改记录。

<script>
    import {mapMutations} from 'vuex'
    export default {
        name: "HelloWorld",
        // 同样的,我们用...解构,把对state的操作一一映射到methods中以便调用
        methods: {
            ...mapMutations(['increment', 'decrement']),
            // 这里用方法调用映射出来的操作
            increase () {
                // this.$stroe.commit('increment')
                this.increment()
            },
            decrease () {
                // this.$stroe.commit('decrement')
                this.decrement()
            }
        }
    }
</script>

注意:一定要避免直接对state中的状态进行修改,虽然直接在methods中写this.$store.state.count +=1,也能递增,但是在Vue-devtool中是没有记录的,这样就不符合开发流程,没有规范。

进阶demo

actions中存放的是业务逻辑,我们也可以通过它来修改状态,并且可以避免mutations中的操作直接修改状态

const store = new Vuex.Store({
    // 存放全局状态
    state: {
        count: 0
    },
    // 对state中的数据的一个包装加工(类似于计算属性)
    getter: {

    },
    // 若要修改全局状态,一定要通过mutations来修改,若直接修改state对象,会造成特性的丢失
    mutations: {
        // 传入state参数对其进行操作
        increment (state) {
            state.count += 1; // 访问到state的count进行操作
        },
        decrement (state) {
            state.count -= 1;
        }
    },
    // 存放一些淡出的业务逻辑,不涉及页面行为
    actions: {
        // 我们把对state的操作通过actions来调用
        myIncrease (context) {
            context.commit('increment')
        },

        myDecrease (context) {
            context.commit('decrement')
        }
    }
})
<script>
    import {mapMutations, mapActions} from 'vuex'
    export default {
        name: "HelloWorld",
        methods: {
            ...mapMutations(['increment', 'decrement']),
            ...mapActions(['myIncrease', 'myDecrease']),
            // 这里用方法调用映射出来的actions操作
            increase () {
                this.myIncrease()
            },
            decrease () {
                this.myDecrease()
            }
        }
    }
</script>

效果与之前的增加减少一样的,一般情况下,把状态的改变逻辑写在mutations里面,把复杂的业务逻辑写在actions中,如果actions中需要改变state的状态,就调用mutations中的改变状态的逻辑。

getter的用法

getter类似于计算属性

// 对state中的数据的一个包装加工(类似于计算属性)
    getter: {
        myCount (state) {
            return `这是${state.count}`
        }
    },
import {mapState, mapGetter} from 'vuex'
export default {
        name: "App",
        computed: {
            ...mapState(["count"]),
            ...mapGetter(["myCount"])
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读