Help us understand the problem. What is going on with this article?

Laravel5.5こと始め 〜9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加〜

More than 1 year has passed since last update.

内容

以下の順番にまとめます。
1. MacへのXAMPP+Laravelインストール
2. ユーザログイン機能の追加
3. MVCとルーティングの説明
4. ユーザリストの表示
5. ユーザリストのペジネーション表示
6. ユーザ管理APIの追加
7. Vue.jsとAPIベースのユーザ管理アプリの追加準備
8. Vue.jsとAPIベースのユーザ管理アプリの追加
9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加 ←いまここ
10. APIへのJWTAuth認証の追加
11. Vue.jsとAPIベースのユーザ管理アプリへの認証の追加

9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加

9.1 laravel-vue-paginationのインストール

下記のコマンドを実行して、「laravel-vue-pagination」ライブラリをインストールします。

$ npm install --save-dev laravel-vue-pagination
+ laravel-vue-pagination@1.2.0
added 1 package from 1 contributor and audited 18965 packages in 12.873s
found 11 moderate severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

package.jsonファイルは下記の通りとなります。

{
    "private": true,
    "scripts": {
... (中略)
    },
    "devDependencies": {
        "ajv": "^6.5.2",
        "axios": "^0.18",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "jquery": "^3.2",
        "laravel-mix": "^2.0",
        "laravel-vue-pagination": "^1.2.0",
        "lodash": "^4.17.4",
        "popper.js": "^1.12",
        "vue": "^2.5.7",
        "vue-axios": "^2.1.2",
        "vue-router": "^3.0.1",
        "vuetable-2": "^1.7.5"
    }
}

9.2 APIをペジネーション用に修正

「app/Http/Controllers/UserController.php」で実装されているユーザ管理用のAPIですが、ユーザ情報のリスト表示部分にぺじネーションを適用しますので、indexメソッドを下記の通り修正します。if文部分は得られたユーザリストが空の場合は「Record Not Found」のエラーをJSONで返すようにしています。

app/Http/Controllers/UserController.php
...
    public function index() // ユーザ一覧を返します
    {
        $users = User::paginate(1);
        if($users->getCollection()->isEmpty()) {
          return response()->json(['error'=>'Record Not Found'],404);
        }
        return $users;
    }
...

「php artisan serve」を実行して、APIの変化を確認します。

修正前は、「Laravel5.5こと始め 〜6. ユーザ管理APIの追加〜」に記載したとおり下記の通りのレスポンスがかえります。

$ curl -X GET http://localhost:8000/api/users 2>/dev/null | jq
[
  {
    "id": 1,
    "name": "test1",
    "email": "test1@test.com",
    "created_at": "2018-07-09 13:43:53",
    "updated_at": "2018-07-09 13:43:53"
  },
  {
    "id": 2,
    "name": "test2",
    "email": "test2@test.com",
    "created_at": "2018-07-09 13:43:53",
    "updated_at": "2018-07-09 13:43:53"
  },
  {
    "id": 3,
    "name": "test3",
    "email": "test3@test.com",
    "created_at": "2018-07-09 13:43:54",
    "updated_at": "2018-07-09 13:43:54"
  }
]

1行でペジネーションするよう修正した後は下記の通りになります。

$ curl -X GET http://localhost:8000/api/users 2>/dev/null | jq
{
  "current_page": 1,
  "data": [
    {
      "id": 1,
      "name": "test1",
      "email": "test1@test.com",
      "created_at": "2018-07-09 13:43:53",
      "updated_at": "2018-07-09 13:43:53"
    }
  ],
  "first_page_url": "http://localhost:8000/api/users?page=1",
  "from": 1,
  "last_page": 3,
  "last_page_url": "http://localhost:8000/api/users?page=3",
  "next_page_url": "http://localhost:8000/api/users?page=2",
  "path": "http://localhost:8000/api/users",
  "per_page": 1,
  "prev_page_url": null,
  "to": 1,
  "total": 3
}

2ページ目はパラメータにpageをセットして実行します。

$ curl -X GET http://localhost:8000/api/users?page=2 2>/dev/null | jq
{
  "current_page": 2,
  "data": [
    {
      "id": 2,
      "name": "test02",
      "email": "test2@test.com",
      "created_at": "2018-07-09 13:43:53",
      "updated_at": "2018-07-09 14:03:20"
    }
  ],
  "first_page_url": "http://localhost:8000/api/users?page=1",
  "from": 2,
  "last_page": 3,
  "last_page_url": "http://localhost:8000/api/users?page=3",
  "next_page_url": "http://localhost:8000/api/users?page=3",
  "path": "http://localhost:8000/api/users",
  "per_page": 1,
  "prev_page_url": "http://localhost:8000/api/users?page=1",
  "to": 2,
  "total": 3
}

存在しない100ページ目を表示しようとすると、「Record Not Found」と言われます。

$ curl -X GET http://localhost:8000/api/users?page=100 2>/dev/null | jq
{
  "error": "Record Not Found"
}

ここでペジネーション有無でデータ部分の構造がどう異なるか見てみましょう。
ペジネーションなしの場合は以下の通りで「[{(ここにデータが入る)},...]という構造を持ちます。

[
  {
    "id": 1,
    "name": "test1",
    "email": "test1@test.com",
...
  },
...

]

ペジネーションありの場合は以下の通りで「{"current_page":1,"data":[{(ここにデータが入る)},...],...}]」という構造を持ち、なしの場合の構造がタイトル"data"配下に配置される形になっています。

{
  "current_page": 1,
  "data": [
    {
      "id": 1,
      "name": "test1",
      "email": "test1@test.com",
...
    },
...
  ],
...
  "first_page_url": "http://localhost:8000/api/users?page=1",
  "from": 1,
  "last_page": 3,
  "last_page_url": "http://localhost:8000/api/users?page=3",
  "next_page_url": "http://localhost:8000/api/users?page=2",
  "path": "http://localhost:8000/api/users",
  "per_page": 1,
  "prev_page_url": null,
  "to": 1,
  "total": 3
}

そのため、「UsersIndex.vue」において、ペジネーションなしで「app.users = resp.data;」と表現したものが、「app.users = resp.data.data;」となります。また、

9.3 Vueの修正

1. UsersIndex.vueの修正

resources/assets/js/components/UsersIndex.vue
<template>
  <div>
    <div class="form-group">
      <router-link :to="{name: 'createUser'}" class="btn btn-success">Create new user</router-link>
    </div>
    <div class="panel panel-default">
      <div class="panel-body">
        <table class="table table-bordered table-striped">
        <thead>
          <tr>
            <th>Name</th>
            <th>Email</th>
            <th width="100">&nbsp;</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="user, index in users.data"> <!--修正-->
            <td>{{ user.name }}</td>
            <td>{{ user.email }}</td>
            <td>
              <router-link :to="{name:'editUser',params:{id:user.id}}" class="btn btn-xs btn-default">Edit</router-link>
              <a href="#" class="btn btn-xs btn-danger" v-on:click="deleteEntry(user.id, index)">Delete</a>
            </td>
          </tr>
        </tbody>
        </table>
        <pagination :data="users" @pagination-change-page="getResults"></pagination> <!--追加-->
      </div>
    </div>
  </div>
</template>

<script>
  import http from '../http.js'
  import pagination from 'laravel-vue-pagination'; // 追記
  export default {
    data: function () {
      return {
        users: {} // 修正
      }
    },
    // 追記ここから
    components: { 
      pagination
    },
    // 追記ここまで
    mounted() {
      this.getResults();
    },
    methods: {
      getResults(page=1) { // 修正
        var app = this;
        http.get('users?page='+page,resp=>{ // 修正
          app.users = resp.data;
        })
      },
      deleteEntry(id, index) {
        if (confirm("Do you really want to delete it?")) {
          var app = this;
          http.delete('users/'+id,app.$router.go(0))
        }
      }
    }
  }
</script>

2. 「npm run dev」コマンドの実行

$ npm run dev
 DONE  Compiled successfully in 5155ms                                                                                                           12:56:20

       Asset     Size  Chunks                    Chunk Names
  /js/app.js  1.46 MB       0  [emitted]  [big]  /js/app
/css/app.css   196 kB    0, 0  [emitted]         /js/app, /js/app

これにより、「public/js/app.js」が更新されます。

ユーザ管理アプリの起動

実装したユーザ管理アプリをテストします。いつものように「php artisan serve」を実行して開発用サービスを開始します。

1. 「http://localhost:8000/home2 」にアクセスし、ログインします。

http://localhost:8000/home2 にアクセスするとログインしていない場合ログイン画面が表示されますのでログインします。

スクリーンショット 2018-06-30 19.05.08.png

2. ユーザリストが表示されます。

スクリーンショット 2018-07-16 21.37.47.png

3. ユーザを作成します。

「Create new user」ボタンを押下して、ユーザ情報を入力して「Create」ボタンを押下します。

スクリーンショット 2018-06-30 19.05.54.png

ユーザが追加されてリスト表示されます。

スクリーンショット 2018-07-16 21.39.35.png

4. ユーザ情報を編集します。

リストから編集したい行の「Edit」を押下して表示される「Edit User」画面でユーザ情報を編集し、「Edit」ボタンを押下します。

スクリーンショット 2018-06-30 19.15.19.png

確認ダイアログが表示されますので、OKボタンを押下します。

スクリーンショット 2018-06-30 19.15.30.png

編集された結果を反映したユーザ情報がリストされます。

スクリーンショット 2018-07-16 21.40.58.png

5. ユーザ情報を削除します。

リストから削除したいユーザのDeleteボタンを押下すると、確認ダイアログが表示されるのでOKボタンを押下します。

スクリーンショット 2018-07-16 21.41.56.png

削除が反映されて一覧が表示されます。

スクリーンショット 2018-07-16 21.42.29.png

以上、「9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加」が完了です。

次は、「10. APIへのJWTAuth認証の追加」です。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away