美文网首页Frontend_Developmentvue.jsVueJS必备
Vuex 通俗版教程告诉你Vuex怎么用

Vuex 通俗版教程告诉你Vuex怎么用

作者: _littleTank_ | 来源:发表于2017-08-28 15:29 被阅读2147次

    写在文前:

    最近一直在用vue开发项目,写来写去就是那么些方法,对于简单的项目一些常用的vue方法足以解决,但是涉及到页面状态,权限判断等一些复杂的传值,vuex是必须的。对于vuex也运用一段时间,但是总觉得少了点什么,或者停留在会用的状态,理解不了精髓,当然了估计水平还没达到。所以一直想找个时间总结一下vuex。一来深入的了解,二来也方便以后查阅。

    import Vue from 'vue'; 
    import Vuex from 'vuex'; 
    Vue.use(Vuex); 
    
    const store = new Vuex.Store({ 
           state: { count: 0 },
           mutations: {
                increment (state) { 
                    state.count++ 
                } 
          }
     })
    

    以上就是一个最简单的Vuex,每一个Vuex应用就是一个store,在store中包含组件中的共享状态state和改变状态的方法(暂且称作方法)mutations。

    vuex的核心是:state,getter,actions,mutations

    1、state

    state就是根据你项目的需求,自己定义的一个数据结构,里面可以放些通用的状态。

    const state = {
      openId:"",
      storeId:"",
      storeName:''
    }
    

    例如上面所写的,这些状态可以在各个页面通过vuex访问。如下:

    this.$store.state.openId = "111"
    

    之前我一直通过上面的方式来修改state里面的状态值,行,肯定能用,但是好像官方并不建议我们这样使用,而是建议使用mutations来改变state里面的值,因为不通过mutations改变state,状态不会被同步。至于mutations下面会讲到。

    2、getter

    getter怎么理解呢?通俗的理解可以认为是getter里的函数就是vuex里的计算属性,类似于computed函数。

    const store = new Vuex.Store({ 
           state: {
                count: 0 
           },
           getters: {  // getters
                countAdd: function (state) {
                     return state.count++
                }
           },
           mutations: {
                increment (state) { 
                    state.count++ 
                } 
          }
     })
    

    getter函数怎么用呢?如上vuex里定义了一个getter函数countAdd。我们可以在vue文件里的computed计算属性里引用,如下。

    computed: {
         ...mapGetters{["countAdd"]} 
         show:function(){
               alert("这个是测试页面")
         }
    }
    

    这样我们可以直接在vue页面里取到countAdd的值{{countAdd}}即为1。可惜在我的项目里目前还没用到getter,可能写的少了,还没理解其中的要义。

    3、mutations

    官方定义:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutations 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
        increment (state) {
          // 变更状态
          state.count++
        }
      }
    })
    

    你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:

    store.commit('increment')
    

    也可以向store.commit传入第二参数,也就是mutation的payload:

    mutaion: {
        increment (state, n) {
            state.count += n;
        }
    }
    store.commit('increment', 10);
    

    但是有时候,单个传入n可能并不能满足我们的业务需要,这时候我们可以选择传入一个payload对象:

    mutation: { 
         increment (state, payload) { 
                state.totalPrice += payload.price + payload.count; 
         } 
    } 
    store.commit({
         type: 'increment', 
         price: 10, 
         count: 8
     })
    

    不例外,mutations也有映射函数mapMutations,帮助我们简化代码,使用mapMutations辅助函数将组件中的methods映射为store.commit调用。

    import { mapMutations } from 'vuex'
    export default {
      methods: {
        ...mapMutations({
            add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
        })
      }
    }
    这样我们可以在vue文件里直接调用函数:this.add()而不用this.$store.commit('increment')这样写了,简化了很多。
    需要注意:Mutations必须是同步函数。
    如果我们需要异步操作,Mutations就不能满足我们需求了,这时候我们就需要Actions了。
    

    4、action

    Action 类似于 mutation,不同在于:
    Action 提交的是 mutation,而不是直接变更状态。
    Action 可以包含任意异步操作。
    官方demo如下:

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('increment')
        }
      }
    })
    

    如果我在vue页面里想用action,我们可以分发 Action,Action 通过 store.dispatch 方法触发:

    store.dispatch('increment')
    

    Actions 支持同样的载荷方式和对象方式进行分发:

    // 以载荷形式分发
    store.dispatch('incrementAsync', {
      amount: 10
    })
    
    // 以对象形式分发
    store.dispatch({
      type: 'incrementAsync',
      amount: 10
    })
    

    我们也可以运用其映射函数:mapActions

    methods:{
         ...mapActions{[
               "add":"increment "//函数命名不相同
           //  "increment ":"increment "//函数命名相同
         ]}
    }
    调用:this.add()即可。相同时候调用:this.increment()
    

    Modules

    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

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

    总结起来:mutation 只管存,你给我(dispatch)我就存;action只管中间处理,处理完我就给你,你怎么存我不管(所有的改变state状态的都是mutation 来操作);Getter 我只管取,我不改的(类似计算属性)。

    关于vuex目前也就了解这么多,在实际项目中vuex用什么,怎么用,还需要灵活改变,以后慢慢摸索吧。上面的示例很多都是vuex文档上的,总结起来还是需要多看文档,在实际项目中运用,才是最好的办法吧。

    相关文章

      网友评论

      本文标题:Vuex 通俗版教程告诉你Vuex怎么用

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