美文网首页VueJS
VUEX的简单运用

VUEX的简单运用

作者: 感觉不错哦 | 来源:发表于2018-10-30 17:27 被阅读100次

    什么是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的方法 将其转换为异步

    dispatch

    修改了一下代码,可以直接复制,为了让效果更明显

    store.js

        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 actions ={
            addAction(context){
                context.commit('add',10)  
            },
            reduceAction({commit}){
                commit('reduce')
            }
        }
        export default new vuex.Store({
            state,mutations,actions
        })
    

    vue组件

    <template>
      <div>
            {{count}}
            <p>   
                <button @click="addAction">+</button>
                <button @click="reduceAction">-</button>
            </p>
        </div>
    </template>
    
    <script>
            import store from '@/vuex/store'
            import {mapState,mapMutations,mapActions,mapGetters} from 'vuex';
            export default {
                    store,
              computed:{
                  ...mapState(["count"]),
                  
              },
                methods:{
                   // ...mapActions(['addAction','reduceAction'])
    
                    addAction(){
                      this.$store.dispatch('addAction',10)
                    },
                    reduceAction(){
                      this.$store.dispatch('reduceAction')
                    }
                }
            }
    </script>
    
    <style>
    </style>
    

    可以做下比较,dispatch其实就是相当于mutation的commit调用,我们使用map映射省略dispatch,昨天有位小伙伴问我dispatch是什么突然卡了,果然太久没敲就尴尬了

    区别:

    dispatch:含有异步操作,写法: this.$store.dispatch('actions方法名',值)

    commit:同步操作,写法:this.$store.commit('mutations方法名',值)

    还是建议多用map映射

    vuex-persistedstate简单使用

    npm install vuex-persistedstate -D

    在store.js中引入

        import Vue from 'vue'
        import vuex from 'vuex'
        import createPersistedState from 'vuex-persistedstate'
        Vue.use(vuex);         
    
        const state={
            count:1
        }
        const mutations={
            add(state,n){
                state.count+=n;
            },
            reduce(state){
                state.count--;
            }
        }
        const actions ={
            addAction(context){
                context.commit('add',10)  
            },
            reduceAction({commit}){
                commit('reduce')
            }
        }
        export default new vuex.Store({
            plugins: [createPersistedState()],  //添加这句即可 默认存储本地localSrorage  更多配置可以百度一下
            state,mutations,actions
        })
    

    因为我们的操作都是操作state的 因此只存储state的变化 小伙伴可以自己试一下

    相关文章

      网友评论

        本文标题:VUEX的简单运用

        本文链接:https://www.haomeiwen.com/subject/kwugtqtx.html