Laravel Paginated Collections with Vue.js

Simplify Data Display & Manipulation with the Ultimate Mixin

Daniel Alvidrez
Nov 9, 2018 · 3 min read

Using a JS Class & Mixin we can setup any Vue Component to deal with our data in a highly integrated manner. To demonstrate this, we’ll build a data table from scratch that interfaces with a paginated Laravel model collection.

This setup is using the class computed properties and methods to manipulate the collection instance contained in the class / mixin which allows Vue to track the changes. I started with a datatable so all the basic methods you would need to sort and filter are available.

You should try to organize your mixins and make them easy to import.
Example: mixins/index.js file.

import HasLoadingState from './HasLoadingState'
import HasCollection from './HasCollection'
export {
HasLoadingState,
HasCollection,
}
import {HasCollection} from './mixins' 
export default {
mixins: [
HasCollection
],
}

HasCollection Class / Mixin

Our basic interface is described as follows:

  • get(field)
    Get an attribute from the collection instance.
  • set(field, value)
    Set an attribute on the collection instance.
  • setState(obj)
    Set the collection instance state.
  • flush()
    Reset the collection instance to it’s default state.
  • append(obj, dupes = false)
    Append an object to the collection data state.
  • prepend(obj, dupes = false)
    Prepend an object to the collection data state.
  • has(obj)
    Does the collection data state contain a specific object?
  • find(obj ={id: 1}, ‘id’)
    Find all objects by property.
  • first(obj ={id: 1}, ‘id’)
    Get the first object by property.
  • update(obj ={id: 1, canceled: true}, ‘id’)
    Update an object by property with new partial properties.
  • remove(obj ={id: 1}, ‘id’)
    Remove an object by property.
  • replace(obj ={…}, ‘id’)
    Replace a full object by property.
  • toggleSortable(String)
    Toggle the sortBy attribute relating to a specific field.
  • isCurrentPage(Number)
    Is the current page equal to the number argument?
  • currentPage
    Current page number (computed getter).
  • previousPage()
    De-increment the page number.
  • nextPage()
    Increment the page number.
  • page(Number)
    Set the page number.
  • items (value getter)
  • hasItems (computed getter)
  • hasPagination (computed getter)
  • hasNextPage (computed getter)
  • hasPreviousPage (computed getter)
  • shouldRenderLinks (computed getter)
  • sort (value getter / setter)
  • orderBy (value getter / setter)
  • perPage (value getter / setter)
  • perPageOptions (value getter)
  • isOrderedBy(String)
    Is the collection ordered by the argument value?
  • isSorted(String)
    Is the collection sorted by the argument value?
  • buildLinks(Number (currentPage), Number (lastPage))
    Build the pagination links.
  • pagination (computed getter)
  • urlParams (computed getter) Primary Watchable Properties

Table Component Implementation

The key to making the collection instance sync with the server is the computed property for the urlParams. By setting up a watcher, we can fire an Axios request to Laravel so our data is synchronized automatically as the class properties are changed.

Vue.component('v-table', require('./comps/v-table'))

HasLoadingState Mixin

This simple mixin is used to provide a basic api for manipulating a localized loading state.

Pagination Component Implementation:

The pagination component accepts the collection instance and a loading state as props. Essentially a continuation of the table component but seperate so it’s reusable.

Table Component Usage (Blade Example)

The table component accepts the route, settings object and columns definition. The row is extracted from the slot scope which allows for easy access to the row data.

Daniel Alvidrez

Written by

Full Stack Developer — Community Moderator @ Laravel PHP Framework Facebook Group