Vuexの使用は、見終わったらわかります

14424 ワード

1.vuexとは
  • VuexはVue専用である.jsアプリケーション開発の状態管理モード.
  • これはグローバル状態のdataであり、任意のコンポーネントがこのデータにアクセスできることを簡単に理解することができます.
  • の2つの特徴:
  • Vuexの状態記憶は応答式である.
  • storeの中のデータの状態を直接変えることができなくて、(commit)mutationを提出することによってデータを変える.

  • 2.簡単なvuex
  • store/indexを定義する.jsファイル
  • import Vue from 'Vue'
    import Vuex from 'Vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex({
        state: {
            count: 0,
            txt1: 'hello',
            txt2: 'world'
        },
        // getters       computed  
        getters:{
            txtLink(state){
                return state.txt1 + state.txt2
            },
            // getter       
            txtLinkLength(state,getters){
                return getters.txtLink.length
            }
        },
        // mutation       
        mutations:{
            increment(state){
                state.count++
            },
            //    
            increment1(state,n){
                state.count+=n
            },
            //      
            increment2(state,obj){
                console.log(obj)
            },
        },
        //   action      
        actions: { 
            //   context    store,   store
            increment (context) {
                //     context   state   getters    
                // const count = context.state.count
                // const txtLink = context.getters.txtLink
                context.commit('increment')
            },
            //    {commit}    context.commit
            // params       ,     ,    
            incrementAsync({commit, state}, params){
                setTimeout(()=>{
                    commit('increment')
                },1000)
            },
    
            // Promise
            actionA({commit}){
                return new Promise((resolve,reject)=>{
                     setTimeout(()=>{
                        commit('increment')
                        resolve()
                    },1000)
                })
            },
            // action      action
            actionB({commit,dispatch}){
             dispatch('actionA').then(res=>console.log(res))
            },
    
            // async await
            // getData(),getOtherData()   Promise
             async actionA ({ commit }) {
                commit('gotData', await getData())
             },
            async actionB ({ dispatch, commit }) {
                await dispatch('actionA') //    actionA   
                commit('gotOtherData', await getOtherData())
            }
      }
    })
    
  • コンポーネント登録store(一般的にmain.js)
  • new Vue({
        el: '#app'
        store,
    })
    
  • コンポーネント内で使用する
  • 
    
    import { mapState } from 'vuex' //           
    import { mapGetters } from 'vuex' //     mapState ,  ..
    import { mapMutations } from 'vuex' 
    import { mapActions } from 'vuex' //     mapMutations ,  ..
    export default{
        data(){
            return{
                localcount:1;
            }
        },
        computed:{
            // state
            count(){
                return this.$store.state.count
            },
            // getters
            txt1(){
                return this.$store.getters.txt1
            },
            // mapState        mapState      
            ...mapState({
                count: state=>state.count,
                //   
                count:'count',
                //   data  
                count(state){
                    return state.count + this.localcount
                }
            }),
            //   mapState      
            ...mapState([
                //       state          ,    (      )
                'count'
            ])
        },
        methods:{
            //      mutation
            add(){
                this.$store.commit('increment')
                // state
                console.log(this.$store.state.count)
                // getters
                console.log(this.$store.getters.txtLink)
            },
            //   mutations    
            add1(){
                this.$store.commit('increment1',10)
                //      
                this.$store.commit('increment2',{ name:'zhangsan'})
                //       
                 this.$store.commit({
                     type:'increment2',
                     amunt:10
                 })
            }
            // mapMutations    
            ...mapMutations([
            'increment', //   `this.increment()`     `this.$store.commit('increment')`
    
            // `mapMutations`      :
            'incrementBy(10)' //   `this.incrementBy(amount)`     `this.$store.commit  ('incrementBy', amount)`
            ]),
            ...mapMutations({
                add: 'increment' //   `this.add()`     `this.$store.commit('increment')`
            }),
    
            //    Action     mutations
            add(){
                this.$store.dispatch('increment')
                //    
                this.$store.dispatch('incrementAsync',{
                    amout:10
                })
                //        
                this.$store.dispatch({
                    type: 'incrementAsync',
                    amount: 10
                })
            },
            // Action    Promise
            add(){
                this.$store.dispatch('actionA').then(res=>console.log(res)).catch(err=>console.log(err))
            }
        }
    }
    
    
  • 注意:
  • Mutationは同期関数でなければならない(mutationがトリガーされたとき、コールバック関数はまだ呼び出されていないため、devtoolsはいつコールバック関数が実際に呼び出されるか分からない--実質的にコールバック関数で行われた状態の変化は追跡できない.)
  • store.dispatchは、異なるモジュールで複数のaction関数をトリガすることができる.この場合、返されるPromiseは、すべてのトリガ関数が完了した場合にのみ実行されます.

  • 3. Module
  • 状態が多く、モジュール分割が必要な場合はModule
  • を使用できます.
  • 簡単なmodule
  • const moduleA = {
      state: () => ({ 
          count:0
       }),
      mutations: { 
          increment(state){
              state.count++
          }
       },
      actions: { 
          incrementSync({commit}){
              commit('increment')
          }
       },
      getters: { 
          countGetter(state){
              return state*2
          }
       }
    }
    
    const moduleB = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    
    //          
    // a  state
    store.state.a.count
    // a  getters
    store.getters.a.count
    // a  mutations
    store.commit('a/increment')
    // a  mutations
    store.dispatch('a/incrementSync')
    
    store.state.b // -> moduleB     ...
    
  • モジュールの状態
  • const moduleA = {
      state: () => ({
        count: 0
      }),
      mutations: {
        increment (state) {
          //     `state`           
          state.count++
        }
      },
     //         getter,                 :
      getters: {
        doubleCount (state,getters,rootState) {
          return state.count + rootState.count
        }
      },
    
      actions: {
        increment ({ state, commit, rootState }) {
            // rootState        
          if ((state.count + rootState.count) % 2 === 1) {
            commit('increment')
          }
        }
      }
    
    }
    
  • ネーミングスペース
  • のデフォルトでは、モジュール内部のaction、mutation、getterはグローバルネーミングスペースに登録されています.これにより、複数のモジュールが同じmutationまたはactionに応答できるようになります.
  • モジュールのカプセル化と多重化を望む場合は、namespaced:trueを追加することで、ネーミングスペース付きモジュールにすることができます.モジュールが登録されると、そのすべてのgetter、action、mutationは、モジュール登録のパスに基づいて自動的に名前を調整します.
  • グローバルネーミングスペース内でactionを配布したりmutationをコミットしたりする必要がある場合は、{root:true}を第3パラメータとしてdispatchまたはcommitに渡せばよい.
  • modules: {
      foo: {
        namespaced: true,
    
        getters: {
          //        getter  ,`getters`      
          //       getter           `rootGetters`
          someGetter (state, getters, rootState, rootGetters) {
            getters.someOtherGetter // -> 'foo/someOtherGetter'
            rootGetters.someOtherGetter // -> 'someOtherGetter'
          },
          someOtherGetter: state => { ... }
        },
    
        actions: {
          //       , dispatch   commit       
          //        `root`        dispatch   commit
          someAction ({ dispatch, commit, getters, rootGetters }) {
            getters.someGetter // -> 'foo/someGetter'
            rootGetters.someGetter // -> 'someGetter'
    
            dispatch('someOtherAction') // -> 'foo/someOtherAction'
            dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
    
            commit('someMutation') // -> 'foo/someMutation'
            commit('someMutation', null, { root: true }) // -> 'someMutation'
          },
          someOtherAction (ctx, payload) { ... }
        }
      }
    }
    
  • ネーミングスペース付きモジュールにグローバルactionを登録する必要がある場合はroot:true
  • を追加できます.
    {
      actions: { 
          //       action
        someOtherAction ({dispatch}) {
          dispatch('someAction')
        }
      },
      modules: {
        foo: {
          namespaced: true,
    
          actions: {
            someAction: {
              root: true, //    root       actions
              handler (namespacedContext, payload) { ... } // -> 'someAction'
            }
          }
        }
      }
    }
    
  • ネーミングスペース付きバインド関数
  • computed: {
      ...mapState({
        a: state => state.some.nested.module.a,
        b: state => state.some.nested.module.b
      })
    },
    methods: {
      ...mapActions([
        'some/nested/module/foo', // -> this['some/nested/module/foo']()
        'some/nested/module/bar' // -> this['some/nested/module/bar']()
      ])
    }
    
    //   
    
    computed: {
      ...mapState('some/nested/module', {
        a: state => state.a,
        b: state => state.b
      })
    },
    methods: {
      ...mapActions('some/nested/module', [
        'foo', // -> this.foo()
        'bar' // -> this.bar()
      ])
    }
    
  • createNamespacedHelpersを使用して、ネーミングスペースベースの補助関数を作成します.
  • import { createNamespacedHelpers } from 'vuex'
    
    const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
    
    export default {
      computed: {
        //   `some/nested/module`    
        ...mapState({
          a: state => state.a,
          b: state => state.b
        })
      },
      methods: {
        //   `some/nested/module`    
        ...mapActions([
          'foo',
          'bar'
        ])
      }
    }
    
  • モジュール動的登録
  • storeの作成後、storeを使用できます.registerModuleメソッド登録モジュール:
  • 以降はstoreを通過することができる.state.マイModuleとstorestate.nested.myModuleアクセスモジュールのステータス.
  • import Vuex from 'vuex'
    
    const store = new Vuex.Store({ /*    */ })
    
    //      `myModule`
    store.registerModule('myModule', {
      // ...
    })
    //        `nested/myModule`
    store.registerModule(['nested', 'myModule'], {
      // ...
    })
    

    3.1ネーミングスペースの注意点
  • ネーミングスペース(namespaced:false)
  • を持たない
  • stateの呼び出しは昇格せず、getter、metations、actionsの使用は最上位
  • に昇格します.
    const moduleA = {
      state: () => ({ 
          count:0
       }),
      mutations: { 
          increment(state){
              state.count++
          }
       },
      actions: { 
          incrementSync({commit}){
              commit('increment')
          }
       },
      getters: { 
          countGetter(state){
              return state*2
          }
       }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    
    //          
    store.state.a.count 
    store.getters.a.count
    store.commit('increment') //        a/increment 
    store.dispatch('incrementSync')
    
  • ネーミングスペース(namespaced:true)
  • const moduleA = {
      namespaced: true,
      state: () => ({ 
          count:0
       }),
      mutations: { 
          increment(state){
              state.count++
          }
       },
      actions: { 
          incrementSync({commit}){
              commit('increment')
          }
       },
      getters: { 
          countGetter(state){
              return state*2
          }
       },
       moduleB{
           ...
       }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    
    //          
    store.state.a.count 
    store.getters.a.count //              
    store.commit('a/increment') //              
    store.dispatch('a/incrementSync')
    - PS :    A       b  
    a b        
    store.state.a.b.count 
    store.getters.a.b.count1 //              
    store.commit('a/b/increment1') //              
    store.dispatch('a/b/incrementSync1')
    a       b        (getter,metations  actions          ,               ,                    ,               ,    duplicate getter key: xxx)
    store.state.a.b.count 
    store.getters.a.count1 
    store.commit('a/increment1') 
    store.dispatch('a/incrementSync1')
    

    4.いくつかの規則
  • アプリケーションレベルのステータスは、単一storeオブジェクトに集中する必要があります.
  • がmutationをコミットすることは、ステータスを変更する唯一の方法であり、このプロセスは同期される.
  • 非同期論理はactionにカプセル化されるべきである.

  • 5.各部パラメータ説明
    5.1コンストラクタオプション
  • state
  • タイプ:Object|Function
  • パラメータなし
  • moduleでオブジェクト関数を使用すると、data(){reutrn{}}
  • のようにmoduleを再利用するのに役立ちます.
  • mutations
  • タイプ:{[type:string]:Function}
  • stateを第1のパラメータとし、payloadを第2のパラメータとして(オプション)入力パラメータ
  • である.
    mutations:{
        ADD(state,payload){
    
        }
    }
    
  • actions
  • タイプ:{[type:string]:Function}
  • contextは第1パラメータとして、payloadは第2パラメータとして(オプション).
  • actions:{
        ADD(context,payload){
            
        }
    }
    //   
    actions:{
        ADD({state,commit,dispatch,getters},payload){
            
        }
    }
    
  • contextオブジェクトには、
  • というプロパティがあります.
    {
      state,      //     `store.state`,           
      rootState,  //     `store.state`,       
      commit,     //     `store.commit`
      dispatch,   //     `store.dispatch`
      getters,    //     `store.getters`
      rootGetters //     `store.getters`,       
    }
    
  • getters
  • タイプ:{[key:string]:Function}
  • storeにgetterを登録し、getterメソッドは次のパラメータを受け入れます:
  • state,     //                  
    getters,   //     store.getters
    
  • モジュールに定義されている場合:
  • state,       //                  
    getters,     //     store.getters
    rootState    //     store.state
    rootGetters  //    getters
    
  • modules
  • タイプ:Object
  • サブモジュールを含むオブジェクトはstoreにマージされます.長さは
  • です.
    {
      key: {
        state,
        namespaced?,
        mutations,
        actions?,
        getters?,
        modules?
      },
      ...
    }
    

    5.2例の方法
  • commit
  • commit(type: string, payload?: any, options?: Object)
  • commit(mutation: Object, options?: Object)
  • dispatch
  • dispatch(type: string, payload?: any, options?: Object): Promise
  • dispatch(action: Object, options?: Object): Promise
  • 詳細については、文書Vuex公式リンク
  • を参照してください.