ایجاد کامپوننت صفحه بندی با لاراول 5.3 و Vuejs

ایجاد کامپوننت صفحه بندی با لاراول 5.3 و Vuejs

کامپوننت ها یکی از امکانات بسیار قوی Vue می باشند. به کمک آن ها امکان گسترش المان های HTML و ساختن قطعه کد هایی با توانایی استفاده مجدد می باشد. در سطوح بالاتر کامپوننت ها المان شخصی سازی شده است که با کمک Vue  میتوان به آن ها رفتار مورد نظر خود را می توانید اضافه نمایید.
در این مقاله نحوه تولید کامپوننت صفحه بندی در لاراول 5.3 و Vue  2 شرح داده می شود.
در مرحله اول یک نسخه خام از لاراول نصب نمایید. پایگاه داده مورد نظر خود را بسازید و در فایل env مشخصات آن را وارد نمایید. سپس دستور migration را اجرا و جداول لازم را بسازید.
با اجرای دستور php artisan migrate جدول کاربران در پایگاه داده ساخته شده است. با استفاده از دستور php artisan tinker و factory('App\User', 100)->create(); تعداد 100 کاربر جدید به جدول خود اضافه نمایید. حال میخواهیم نمایش لیست این 100 کاربر را صفحه بندی نماییم. 
حال این دو مسیر را در فایل web.php ایجاد نمایید.

<?php
Route::get('user/api',[
	'as' => 'user.api',
	'uses' => 'API\UserApiController@index'
]);
Route::get('users',[
	'as' => 'users.index',
	'uses' => 'UserController@index'
]);

مسیر اول لیست کاربران را به صورت json باز میگرداند و مسیر دوم لیست کاربران را به سمت فایل نمایش آن ارسال می نماید.
حال کنترل UserApiController را در پوشه Controllers/API می سازیم و متد index جهت نمایش لیست صفحه بندی شده کاربران را می سازیم.

<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\User;
/**
 * Class UserApiController
 * @package App\Http\Controllers\API
 */
class UserApiController extends Controller
{
    /**
     * @var User
     */
    private $user;
    /**
     * UserApiController constructor.
     * @param User $user
     */
    public function __construct(User $user)
    {
    	$this->user = $user;
    }
    /**
     * return paginated records of users
     * 
     * @return \Illuminate\Http\JsonResponse
     */
    public function index()
    {
    	$users = $this->user->paginate(5);
        
    	return response()->json($users);
    }
}

جهت مشاهده لیست صفحه بندی شده از این آدرس می توانید استفاده نمایید.
Localhost:8000/user/api?page=1
لیست به این صورت نمایش داده می شود.

ایجاد کامپوننت صفحه بندی در لاراول و Vuejs
حال UserController و متد index جهت نمایش لیست نمای لاراول را نیز می سازیم.

<?php
namespace App\Http\Controllers;
/**
 * Class UserController
 * @package App\Http\Controllers
 */
class UserController extends Controller
{
    /**
     * return to the users index view
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index()
    {
    	return view('users.index');
    }
}

در پوشه بندی نماهای لاراول یک فایل جهت ادرس دهی به فایل css و js خود بسازید.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
   <meta name="csrf-token" content="{{ csrf_token() }}">
  <title>{{ config('app.name', 'Laravel') }}</title>
  <link href="/css/app.css" rel="stylesheet">
</head>
<body>
  <div id="app">
    <nav class="navbar navbar-default navbar-static-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="{{ url('/') }}">
            {{ config('app.name', 'Laravel') }}
          </a>
        </div>
      </div>
    </nav>
    @yield('content')
  </div>
    <script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

حال که این فایل را آماده نمودید یک فایل با نام index.blade.php در مسیر پوشه views/users با این محتوا بسازید

@extends('layouts.app')
@section('content')
  <div class="container">
    <table class="table table-bordered">
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Created At</th>
      </tr>
      <tr v-for="user in users.data">
        <td>@{{ user.name }}</td>
        <td>@{{ user.email }}</td>
        <td>@{{ user.created_at }}</td>
      </tr>
    </table>
    <vue-pagination  :pagination="users"
                     @paginate="getUsers()"
                     :offset="4">
    </vue-pagination>
    </div>
@endsection

حال در این فایل شما اطلاعات کاربر را در یک جدول مشاهده می کنید. ما ابتدا این اطلاعات را با استفاده از ajax از پایگاه داده دریافت و به متغیر کاربر خود با کمک Vue  اختصاص می دهیم.
در لاراول Vue  به صورت پیش فرض وجود دارد. تنها لازم است با استفاده از دستور npm install و اجرای gulp آن را راه اندازی نمایید. حال یک فایل با نام pagination.vue در آدرس پوشه resources/assets/js/components با محتوای زیر می سازیم. بعد از تغییر صفحه محتوای صفحه فعلی با داده های درخواست شده جایگزین می شوند.

<template>
    <ul class="pagination">
    <li v-if="pagination.current_page > 1">
        <a href="javascript:void(0)" aria-label="Previous" v-on:click.prevent="changePage(pagination.current_page - 1)">
            <span aria-hidden="true">«</span>
            </a>
        </li>
    <li v-for="page in pagesNumber" :class="{'active': page == pagination.current_page}">
        <a href="javascript:void(0)" v-on:click.prevent="changePage(page)">{{ page }}</a>
        </li>
    <li v-if="pagination.current_page < pagination.last_page">
        <a href="javascript:void(0)" aria-label="Next" v-on:click.prevent="changePage(pagination.current_page + 1)">
            <span aria-hidden="true">»</span>
            </a>
        </li>
    </ul>
</template>
<script>
  export default{
      props: {
      pagination: {
          type: Object,
          required: true
      },
      offset: {
          type: Number,
          default: 4
      }
    },
    computed: {
      pagesNumber() {
        if (!this.pagination.to) {
          return [];
        }
        let from = this.pagination.current_page - this.offset;
        if (from < 1) {
          from = 1;
        }
        let to = from + (this.offset * 2);
        if (to >= this.pagination.last_page) {
          to = this.pagination.last_page;
        }
        let pagesArray = [];
        for (let page = from; page <= to; page++) {
          pagesArray.push(page);
        }
          return pagesArray;
      }
    },
    methods : {
      changePage(page) {
        this.pagination.current_page = page;
        this.$emit('paginate');
      }
    }
  }
</script>

حال فایل assets/js/app.js را که حاوی ساختار Vue  می باشد را ساخته و کامپوننت صفحه بندی ساخته شده را در آن وارد نمایید. جهت درخواست داده ها از پایگاه داده از axios که بر اساس درخواست HTTP در سمت کاربری برای مرورگر می باشد استفاده می کنیم. فایل app.js به این صورت خواهد بود.

require('./bootstrap');

import VuePagination from './components/Pagination.vue';
import axios from 'axios';

axios.defaults.headers.common = {
    'X-Requested-With': 'XMLHttpRequest',
    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
};


const  app = new Vue({
    el: '#app',
    data: {
        users: {
            total: 0,
            per_page: 2,
            from: 1,
            to: 0,
            current_page: 1
        },
        offset: 4,
    },
    mounted() {
        this.getUsers();
    },
    components: {
        VuePagination,
    },
    methods: {
        getUsers() {
            axios.get(`/user/api?page=${this.users.current_page}`)
                .then((response) => {
                    this.users = response.data;
                })
                .catch(() => {
                    console.log('handle server error from here');
                });
        }
    }
});

در gulpfile.js از webpack جهت ساختن فایل js استفاده می کنیم.

const elixir = require('laravel-elixir');

require('laravel-elixir-vue-2');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Sass
 | file for our application, as well as publishing vendor resources.
 |
 */

elixir(mix => {
    mix.sass('app.scss')
       .webpack('app.js');
});

با راه اندازی gulp کامپوننت صفحه بندی خود را به نرم افزار خود افزوده اید. این کامپوننت مجددا در بخش های مختلف نرم افزار قابل استفاده می باشد. قطعه کد زیر نمونه گوش دهنده تغییر صفحه می باشد.

<vue-pagination  :pagination="users"
                  @paginate="getUsers()"
                  :offset="4">
</vue-pagination>

متد getUsers در Vue  شما قرار دارد و در صورتی که در بخش دیگری نیاز به استفاده از صفحه بندی داشته باشید باید یک Vue  جدید بسازید. اما از همان کامپوننت استفاده می شود و تنها ممکن است متد getUsers نیاز به تغییر داشته باشد. 
حال پروژه خود را اجرا نمایید و حاصل این بخش را که مشابه این عکس می باشد مشاهده نمایید. 

لینک github برای کامپوننت صفحه بندی در اینجا قرار داده شده است.

مطالب مشابه