[vue]初探vueエココアプラグインVuex

44277 ワード

なぜVuexというものがあるのですか?
アプリケーション内で実行されるメカニズム、イベント->ステータス->UIは、私たちのフロントエンドがこの2つのプロセスによって大量のコードを生成し、メンテナンスが困難になることがよくあります.
vueの宣言レンダリングは、ステータスとUIの同期の問題を解決し、ステータスの変化によってdomのコードを大量のコマンドで変更する必要がなくなります.
vuexのようなステータス管理のライブラリでは、イベント->ステータスというプロセスのメンテナンスの問題が解決されます.このようなライブラリでは、イベントソースからステータスの変化にマッピングするプロセスを管理します(このマッピングプロセスをビューコンポーネントから剥離し、この部分のコードを整理し、コンポーネントの外部でステータスの管理を行います).
Vuexとグローバルオブジェクトの違い
実は、vuexはグローバルオブジェクトと一定の共通点があります.それは、ステータスがどのくらいのコンポーネントをネストしても、グローバルに共有されることです.
各Vuexアプリケーションのコアはstore(倉庫)です.「store」は基本的にコンテナであり、あなたのアプリケーションのほとんどの状態(state)を含んでいます.Vuexと単純なグローバルオブジェクトには、次の2つの点があります.
Vuexの状態記憶は応答式である.Vueコンポーネントがstoreからステータスを読み出すと、storeのステータスが変化すると、対応するコンポーネントも**の効率的な更新**を得ることができます.
storeの状態を直接変えることはできません.storeのステータスを変更する唯一の方法は、明示的にmutationをコミットすることです.これにより、各ステータスの変化を容易に追跡でき、アプリケーションをよりよく理解するためのツールを実現することができます.
Vuexでよく見られるアプリケーションシーン
管理ステータスと共有ステータス
適用が簡単である場合、親子コンポーネントの通信は、propおよびeventを使用して行うことができる.global event bus(event bus)を使用して、単純な非親子コンポーネント間のコンポーネント間通信を実現する.ただし、**多層コンポーネントが**をネストするなど複雑なシーンでは、vuexを使用するとよりよく対応できます.(event busを使用する欠点は、ステータスが複雑な場合、呼び出しコンポーネントが非常に多く、すべてのコンポーネントの更新を順番に通知することです.各コンポーネントがこのコンポーネントに対して行ったステータス更新はすべてのコンポーネントに通知されます.これにより、非常に複雑になります)vuex状態管理モデルは、統合されたデータセンターStoreを有し、Storeは状態データを維持するために使用される.各コンポーネントが更新されると、データセンターに通知され、データセンターが変更された後、呼び出された各コンポーネントが更新される(vueコンポーネントごとにstateを直接操作するのではなく、データセンターによってステータスの変化とステータスの変化の配布を統合することに相当する)vuexは、stateをデータセンターとし、各コンポーネントがstateを共有することによって、コンポーネント間通信を実現し、このときのデータはコンポーネントとは完全に独立している.(異なるモジュールの操作をクリックすると、めちゃくちゃなイベントを送信する必要はなく、イベントセンターのmutationの動作を呼び出し、モジュール間の共有状態を実現する機能)
中規模の単一ページアプリケーションを構築する必要がある場合、コンポーネントの外部管理ステータスをよりよく管理する方法を考慮する可能性があります.
vuexは、**コンポーネント間通信**(多層ネストされたコンポーネント間の通信の問題)およびデータセンターとして集中的にデータを格納するために使用されることが多い(管理アプリケーションで複雑な状態関係)
vuexはデータストレージセンターとしてvuexstateは、単一ページアプリケーションの開発において、コンポーネントが使用するデータをstateに格納し、actionsにデータ読み書きの論理をカプセル化することができるデータベースとしての役割を果たす.現在、主に2つのデータがvuexを使用して管理されています.
コンポーネント間でグローバルに共有されるデータバックエンド非同期要求によるデータ実際のプロジェクト開発では、バックエンドの非同期要求によるデータをvuexの状態管理に組み入れ、actionsにデータの添削改ざんなどの論理をカプセル化することで、フロントエンドの論理コードをある程度階層化することができ、コンポーネントのコードがページインタラクションやデータレンダリングなどの階層の論理に注目することができる.非同期要求と状態データの持続化などはvuexに管理される
一般的なグローバルデータは、vuexまで管理されます.例えばユーザーデータ、システムデータなど、これらのデータは多くのコンポーネントで使用されています.もちろん、使用するたびに要求することができますが、プログラマーの「潔癖さ」や「ケチさ」などの利点から、一度要求して、あちこちで使用したいと思っています.
このときは自然にlocalStorageに格納されると考えられますが、これらのデータは変化する可能性があり、タイムリーに同期できなかった場合は不正なデータが使用され、データ同期をしてもlocalStorageのデータは応答式ではなく、これらのデータを使用した場所を自動的に更新できないという問題があります.その時からvuexを使い始めたいと思います.
Vuexコードの組織方式vue-routerと同様に、非モジュール化された書き方とモジュール化された書き方がある(実際には、どの書き方も本質的に同じであり、routerまたはstoreの構成データを導出することを目的としている).
管理countとユーザ情報userinfoを例に、vuexコードの組織方式を紹介する
コアコンセプトstate,getter,mutation,action,modulevuex守らなければならないルール
アプリケーションレベルのステータスは、単一のstoreオブジェクトに集中する必要があります.mutationはstateを直接操作する方法(状態を変える唯一の方法)であり、プロセスは同期しなければならない.actioncommitによってmutationをトリガし、それによって間接的に状態を修正し、利点は非同期論理を許容することである.
モジュール化されていない書き方
// 1.   vuex

// 2.
// main.js
import Vuex from 'vuex'

// 3.Vue  vuex 
Vue.use(Vuex)

// 4.  store
const store = new Vuex.Store({
    state: {
        userinfonull// 
        count: 0
    },
    //  mutation mutate state;  ; mutation commit
    mutations: {
        userinfofunction (state, payload{
              state.userinfo = options
            localStorage.userinfo = JSON.stringify(state.userinfo)
        },
        incrementfunction (state, payload{
            state.count += payload.amount
        }
    },
    //  commit mutations mutation ,   state;  ;action dispatch
    actions: {
        incrementfunction (context, payload{
            context.commit('increment', payload)
        },
        incrementAsyncfunction (context{
            // 
            setTimeout(() => {
                var amount = 10// 
                context.commit('increment', { amount })
            }, 1000)
        },
        async userinfo (context) {
            let response = await getUserInfo() //     import
            if (response.ok) {
                let json = await response.json()
                context.commit('userinfo', json)
            }
        }
    },
    getters: {//  、

    }
})

// 5.  store  ,  this.$store 
new Vue({
    el'#app',
    store, // (*)
    render: function (h{
        return h(App)
    }
})

モジュラ表記
// 1.  vuex

// 2.
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
// import ...

// 3.Vue  vuex 
Vue.use(Vuex)

// 4.
//   userinfo   ( , import )
const moduleA = {
    state: {
        userinfonull // 
    },
    mutations: {
        userinfofunction (state, options{
            state.userinfo = options
            localstorage.userinfo = JSON.stringify(state.userinfo)
        }
    },
    actions: {
        async userinfo (context) {
            async userinfo (context) {
                let response = await response.json()
                if (response.ok) {
                    let json = await response.json()
                    context.commit('userinfo', json)
                }
            }
        },
        getters: {//  、

        }
    }
}

//   count   ( , import )
const moduleB = {
    state: {
        count1,
    },
    mutations: {
        increment:function (state, payload{
            state.count += payload
        },
    },
    actions: {
        incrementfunction (context, payload{
              context.comit('increment', payload)  
        },
          incrementAsyncfunction (context{
            // 
            setTimeout(() => {
                var amount = 10// 
                context.commit('increment', { amount })
            }, 1000)
        },  
    },
    getters: {
        doubleCount (state) {
            return state.count * 2
        }
    }
}

export default new Vuex.Store({
    modules: { //  ; ...
        a: moduleA,
        b: moduleB,
    }
})

// store.state.a // -> moduleA 
// store.state.b // -> moduleB 

異なるコンポーネントでの使用または操作ステータス
//    
// App.vue
// 
...
mounted () {
    if (!this.$store.state.userinfo) { // this.$store.state.a.userinfo 
        this.$store.dispatch('userinfo')
    }
}

//   state 
computed: {
    userinfo () {
        return this.$store.state.userinfo
        // return this.$store.state.a.userinfo // 
    },
    count () {
        return this.$store.state.count
        // return this.$store.state.b.count // 
    }
}
//    
// NavBar.vue
...
//   state 
methods: {
    //   commit   mutations   mutation  ,  state 
    addOne () {
        this.$store.commit('increment', { amountthis.price })
    },
    //   dispatch   actions   action  ;  state 
    addTenAsync () {
        this.$store.dispatch('incrementAsync')
    }
}

//   state 
computed: {
    userinfo () {
        return this.$store.state.userinfo
        // return this.$store.state.a.userinfo // 
    }
}
//       
// Manage.vue
...
//   state 
methods: {
    addTwo () {
        this.$store.commit('increment', { amountthis.price })
    }
}

//   state 
computed: {
    count () {
        return this.$store.state.count
        // return this.$store.state.b.count // 
    }
},

要するに、vuexを使用して状態を管理し、異なるモジュールの操作をクリックすると、めちゃくちゃなイベントを送信する必要はなく、イベントセンターのmutationの動作を呼び出すだけで、モジュール間の共有状態の機能を実現する.1つを変更すると、グローバル共有(コンポーネントでもルーティングページコンポーネントでも同期できます)