LoginSignup
1
0

More than 1 year has passed since last update.

Vue-infinite-loading で Vuex を使う

Last updated at Posted at 2021-02-09

はじめに

サーバサイドの開発歴は1年程度で、最近初めて業務でフロントエンド開発を担うようになりました。
フロントエンド開発めちゃくちゃ楽しいです。

記事の目的

さて、JS のライブラリとして Vue.js を使っているのですが、 Vue-infinite-loading という無限スクロールを簡単にに実現できるライブラリがあります。

この無限スクロール機能では API を叩いて データを取得する処理が必要となります。これらの処理を状態管理のライブラリである Vuex で扱いたい、というのが本記事のモチベーションです。

ググってみたのですが、ドキュメントには記載がなく、 Issue にコードの一部が載っている程度でした。私はフロントエンド歴が浅いためか、 Issue だけではすぐに理解が出来ず、試行錯誤の末にやっとできましたので、コードの全体像を載せてみようと思います。

参考

Guide | Vue-infinite-loading

実装例

ドキュメント例と同様に Hacker News の API を利用してニュース記事を取得する想定です。
実際に動かしたわけではないので、あくまでもイメージです。

ポイントは NOTE: としてコメントで記載しております。

store.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

const api = '//hn.algolia.com/api/v1/search_by_date?tags=story';

const store = new Vuex.Store({
  state: {
    page: 1,
    hits: []
  }

  mutations: {
    incrementPage(state) {
      state.page++
    },
    addHits(state, hits) {
      state.hits.push(...hits)
    }
  }

  actions: {
    async fetchHits({commit, state}, loadState) {
      const { data } = await axios.get(api, {
        params: {
          page: state.page
        }
      })

      if (data.hits.length) {
        commit('incrementPage')
        commit('addHits', data.hits)

        // NOTE: loadStateには $state が入っているので、loadState をレシーバとして、 loaded や complete を 呼び出すことで、読み込み状態の制御をできる
        loadState.loadState.loaded()
      } else {
        loadState.loadState.complete()
      }
    }
  }
})

export default store

application.vue

<template>
  <div v-for="(hit, $index) in hits" :key="$index">
    <!-- Hacker News item loop -->
  </div>

  <infinite-loading @infinite="infiniteHandler"></infinite-loading>
</template>

<script>
import { mapState, mapActions } from 'vuex'

export default {
  computed: {
    ...mapState(['hits'])
  },
  methods: {
    ...mapActions(['fetchHits']),
    // NOTE: $state を受け取るメソッドを定義し、ディスパッチ時にに引数として $state を渡す
    infiniteHandler($state) {
      this.fetchHits($state)
    }
  }
}
</script>

最後に

よりよい実装方法などありましたら、教えていただけると幸いです🙏
記事が参考になりましたら、「LGTM」お願いします🙏

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0