シンプルブログ、記事一覧ページの作成②

Vue.js

概要

DRFとVue.jsで、シンプルブログを作るシリーズの一つです。記事一覧ページを作成する続きです。

Vuex

前回、記事一覧ページを作成しました。今のところPostListコンポーネント自身が記事の一覧データを保持しています。しかし、後々ヘッダー内での検索フォームで検索結果の記事一覧を取得したいのですが、この場合はどうでしょう。具体的に言うと、Headerコンポーネント内でAjaxなりで検索結果を取得して、それをPostListコンポーネントのpostListプロパティにセットする必要が出てきますが、それはどうすれば良いのでしょうか。

コンポーネントが単純な親と子の関係ならば難しくはないのですが、並列な関係だったり、ネストが深い場合は結構面倒です。親子間のデータ受け渡しのバケツリレーが発生します。そこで、Vuexが役に立ちます。Vuexは様々な場所で参照されるデータを一元管理することができ、各コンポーネントは自由にデータを参照したり、設定できます。さっそく使っていきましょう。

store/index.jsを次のようにします。

import Vue from 'vue'
import Vuex from 'vuex'
import {UPDATE_POSTS} from "./mutation-types"

Vue.use(Vuex)

export default new Vuex.Store({
    strict: true,
    state: {
        posts: {},
    },
    getters: {
        postList(state) {
            return state.posts
        },
    },
    mutations: {
        [UPDATE_POSTS](state, payload) {
            state.posts = payload
        },
    },
    actions: {
        [UPDATE_POSTS]({commit}, payload) {
            commit(UPDATE_POSTS, payload)
        },
    },
    modules: {}
})

stateにpostsがありますね。ここに取得した記事の一覧を設定します。stateへのアクセスは直接行えるのですが、今回は原則、全てゲッターを通してアクセスするようにします。なので、postsを取得するためのpostListゲッターを定義し、コンポーネントはこれを呼び出して一覧を参照します。

mutationsにはステートを操作する処理を書きます。記事一覧の更新とかですね。また、非同期処が絡むときはactionにも処理を書いて、そこからミューテーションを呼び出してステートを操作するのが本来の流れですが、今回はシンプルに、ステート操作は全てアクションを介して行うことにします。

また、ミューテーションのメソッド名を定数化し、mutation-types.jsというファイルに置いています。このように定数を一ヵ所にまとめておくと、どんな操作ができるのか?といったことが簡単に把握できるようになるのです。store/mutation-types.jsを作って次のようにします。

export const UPDATE_POSTS = 'updatePosts'

今回であれば、postsをupdateする操作があるんだな、ということがわかりますね。では、ストアからデータの参照をしたり、更新したりをしましょう。PostList.vueです。

<script>
    import {mapGetters, mapActions} from 'vuex'
    import {UPDATE_POSTS} from "../store/mutation-types";

    export default {
        name: 'post-list',
        computed: {
          ...mapGetters(['postList'])
        },
        methods: {
          ...mapActions([UPDATE_POSTS])
        },
        created() {
            this.$http(this.$httpPosts)
                .then(response => {
                    return response.json()
                })
                .then(data => {
                    this[UPDATE_POSTS](data)
                })
        }
    }
</script>

変更は<script>の部分だけです。dataオプションは不要になり、computedオプションにて、ストアのpostListゲッターを呼び出せるようにしています。mapGettersで登録しています。あとは今までどおり、v-for="post of postList"のように参照することができます。

また、methodsではmapActionsとしてUPDATE_POSTSアクションを呼び出せるようにしていますね。それをAjax処理の中でthis[UPDATE_POSTS](data)として呼び出しています。結果的に、ストアにあるpostsプロパティにはAjaxの結果取得したdataが設定されます。

これでストアを使うように書き換えました。今までどおりに動作します。

Relation Posts

Comment

記事にコメントする

まだコメントはありません。