VUEX的简单运用

什么是vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能

好的 完全看不懂

简单来讲,我们可以把一些货物一起放在一个仓库之中,可以让我们与货物的距离只有一条通道,当我们去存取货物的时候,里面的东西是共有的,大家都能公用,谁都可以往里面进行存取操作

安装、使用 vuex

npm install vuex --save

在src目录下手动创建目录文件 vuex/store.js

在main.js中配置

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import vuex from 'vuex'
    Vue.use(vuex)
    Vue.config.productionTip = false
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      components: { App },
      template: '<App/>'
    })

在vuex/store.js中配置

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);    //必不可少
    const state={
        count:1
    }
    export default new vuex.Store({  //暴露vuex.store
        state
    })

在需要调用的组件中引入

    import store from '@/vuex/store'
    export default {
        store  //一定要在实例中注册
    }

获取store中的state

    <template>
        <div>
            {{$store.state.count}}  //1
        </div>
    </template>

此处提前说明一下moudle 模块组,随着数据组件状态越来越多,同写一个文件不好维护

新建一个js 暴露出来

    export default {
        state:{
            count:1
        }
    }

在store.js中导入

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    import states from './state'
    export default new vuex.Store({
        modules:{      //此参数固定
          state:states
        }
    })

{{$store.state.state.count}} //1

其实只是相当于多了一层导入,方便我们调用维护状态

回到开始

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    export default new vuex.Store({
        state
    })

简单改变state

<template>
    <div>
        {{$store.state.count}}
        <p>
            <button @click="change">Change</button>
        </p>
    </div>
</template>

<script>
        import store from '@/vuex/store'
        export default {
            store,
            methods:{
                change(){
                    this.$store.state.count++
                }
            }
        }
</script>

<style>

</style>

强行改变vuex的state 是流氓行为(违法)

Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

简单粗暴理解: 我们要把我们需要做状态管理的量放到这里来,然后在后面的操作动它

我们有了state状态树,我们要改变它的状态(值),就必须用vue指定唯一方法 mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。

简单粗暴理解:任何不以mutation的方式改变state的值,都是耍流氓(违法)

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={    //简单编辑操作state的mutations  (固定写法)
        add(state){          //此处的state就是上面的state对象
            state.count++;
        },
        reduce(state){
            state.count--;
        }
    }
    export default new vuex.Store({
        state,mutations
    }) 

在组件中调用mutations

<template>
    <div>
        {{$store.state.count}}
        <p>
             <button @click="$store.commit('add')">+</button>   //此处的调用方法注意一下 是commit
                                                                //可不是$store.mutations.add
             <button @click="$store.commit('reduce')">-</button>
        </p>
    </div>
</template>

<script>
        import store from '@/vuex/store'
        export default {
            store,
        }
</script>

<style>

</style>

此时已经可以通过按钮通过mutations改变state了

在渲染vue的时候,根据钩子函数生命周期渲染不同的DOM,一般情况下我们不用直接引用,而是赋值computed

computed属性可以在输出前,对data中的值进行改变,我们就利用这种特性把store.js中的state值赋值给我们模板中的data值。

        export default {
            store,
            computed:{
                     count(){  //将状态赋值给count
                       return this.$store.state.count;
                     }
            }
        }

相应的改变插值中的内容 效果不变

<template>
    <div>
        {{count}}
        <p>
             <button @click="$store.commit('add')">+</button>
             <button @click="$store.commit('reduce')">-</button>
        </p>
    </div>
</template>

此写法稍微有些麻烦,数据多了更是繁琐

vuex为我们提供了mapState操作

首先先引入mapState

        import store from '@/vuex/store'
        import {mapState} from 'vuex';

在computed中进行赋值 效果是一样的 motations也可运行

           computed:mapState({
                count:state=>state.count
            })

可能箭头函数有点懵

            computed:mapState({
                count:function(state){
                    return state.count
                }
            })

接下来设置一下参数,方法肯定有时候带参数的嘛 在store.js中

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={
        add(state,n){     =>此处增加了一个参数n
            state.count+=n;
        },
        reduce(state){
            state.count--;
        }
    }
    export default new vuex.Store({
        state,mutations
    })

接下来只需要在调用mutation方法处传入实参即可

<template>
    <div>
        {{count}}
        <p>
             <button @click="$store.commit('add',10)">+</button>
             <button @click="$store.commit('reduce')">-</button>
        </p>
    </div>
</template>        

类似开始的state 调用方法有些繁琐 不喜欢看到$store.commit( )

模板获取Mutations方法 vuex也为我们提供了相应的方法

        import store from '@/vuex/store'
        import {mapState,mapMutations} from 'vuex'; =>引入模板

方法 我们写在methods中

 methods:mapMutations([
    'add','reduce'
 ]),

然后改变html 这样就跟vue一样啦

<template>
    <div>
        {{count}}
        <p>   
             <button @click="add(10)">+</button>
             <button @click="reduce">-</button>
        </p>
    </div>
</template>

getters计算过滤操作

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={
        add(state,n){
            state.count+=n;
        },
        reduce(state){
            state.count--;
        }
    }
    const getters = {
        count:function(state){
            return state.count +=100; =>类似filters 过滤得到state
        }
    }
    export default new vuex.Store({
        state,mutations,getters
    })

在组件中获取过滤之后的state

        import store from '@/vuex/store'
        import {mapState,mapMutations} from 'vuex';
        export default {
            store,
            computed:mapState({
                count:function(state){
                    return state.count
                }
            }),
             methods:mapMutations([
                  'add','reduce'
             ]),
        }

我们先分析一下当前代码

我们都知道代码属性相同会覆盖,也就是我如果在写一次coumped属性那么上面的原有属性将会覆盖,此处运用es6的扩展运算符进行改写

      import store from '@/vuex/store'
        import {mapState,mapMutations} from 'vuex';
        export default {
            store,
           computed:{
              ...mapState(["count"]),
              count(){
              return this.$store.getters.count;=>此时count是过滤后的state
              }
           },
             methods:mapMutations([
                  'add','reduce'
             ]),
        }

mapState通过扩展运算符将$store.state.count 映射this.count 这个this 很重要,这个映射直接映射到当前Vue的this对象上。(这句话不懂也可以记一下)

此时有测试的小伙伴可能发现 count是110 110 加的 而不是10 10 加的

因为当count发生改变的时候 先通过getters过滤得到新的state(此时已经+100) 然后由mutation改变+10

用mapGetters简化模板写法

        import store from '@/vuex/store'
        import {mapState,mapMutations,mapGetters} from 'vuex';
        export default {
            store,
           computed:{
              ...mapState(["count"]),
              ...mapGetters(["count"])
           },
             methods:mapMutations([
                  'add','reduce'
             ]),
        }

其实这里mapMutation也可以简写,我想大家知道怎么写了

actions异步修改状态

actions和之前讲的Mutations功能基本一样,不同点是,actions是异步的改变state状态,而Mutations是同步改变状态。至于什么是异步什么是同步这里我就不做太多解释了

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={
        add(state,n){
            state.count+=n;
        },
        reduce(state){
            state.count--;
        }
    }
    const getters = {
        count:function(state){
            return state.count +=100;
        }
    }
    const actions ={
        addAction(context){
            context.commit('add',10)  =>之前说过 mutation方法通过 commit调用  忘记了可以翻翻前面哦
        },
        reduceAction({commit}){
            commit('reduce')
        }
    }
    export default new vuex.Store({
        state,mutations,getters,actions
    })

这是两处不同的引用mutations的方法

增加actions 当然 里面的方法名是自定义的

context — {commit}

context:上下文对象,这里你可以理解称store本身。
{commit}:直接把commit对象传递过来,可以让方法体逻辑和代码更清晰明了。

模板中使用actions

        import store from '@/vuex/store'
        import {mapState,mapMutations,mapGetters,mapActions} from 'vuex';
        export default {
            store,
           computed:{
              ...mapState(["count"]),
              ...mapGetters(["count"])
           },
             methods:{
                 ...mapMutations(['add','reduce']),
                 ...mapActions(['addAction','reduceAction'])
             }
        }

其实写法太简单了 练两下就soeasy了

调用异步方法名

<template>
    <div>
        {{count}}
        <p>   
             <button @click="addAction">+</button>
             <button @click="reduceAction">-</button>
        </p>
    </div>

效果相同 因为只是操作mutation的方法 将其转换为异步

猜你喜欢

转载自blog.csdn.net/qq_26006661/article/details/83826447