Vue.js component là một trong những tính năng mạnh mẽ của framework Vue.js, nó giúp mở rộng các thành phần HTML và có khả năng đóng gói cũng như sử dụng lại. Bài viết này sẽ hướng dẫn bạn tạo ra một component cho phép phân trang với các danh sách dữ liệu lớn, sử dụng Laravel 5.4 và Vue 2. Chúng ta cùng bắt đầu nhé.
1. Tạo ứng dụng Laravel
Tạo một ứng dung khung sử dụng Laravel khá nhanh và đơn giản, bạn tham khảo Cài đặt nhanh ứng dụng Laravel. Chú ý, tạo một database và thiết lập kết nối đến database, chạy php artisan migrate để tạo ra sẵn bảng users trong database. Ứng dụng Laravel này chúng ta sẽ tạo ra tên miền ảo cục bộ là http://pagination.dev để dễ dàng thực hiện. Tiếp theo, chúng ta sẽ sử dụng Laravel Tinker tạo ra dữ liệu mẫu bao gồm 100 người dùng.
c:\xampp\htdocs\pagination>php artisan tinker
Psy Shell v0.8.5 (PHP 5.6.20 ΓÇö cli) by Justin Hileman
>>> factory('App\User',100)->create();
...
App\User {#793
name: "Roxanne Quitzon",
email: "willms.carmela@example.org",
updated_at: "2017-05-21 07:48:36",
created_at: "2017-05-21 07:48:36",
id: 98,
},
App\User {#794
name: "Dr. Emie Tillman",
email: "boyer.della@example.org",
updated_at: "2017-05-21 07:48:36",
created_at: "2017-05-21 07:48:36",
id: 99,
},
App\User {#795
name: "Prof. Katarina Lakin DDS",
email: "egutmann@example.com",
updated_at: "2017-05-21 07:48:36",
created_at: "2017-05-21 07:48:36",
id: 100,
},
],
}
>>>
Ok, như vậy chúng ta đã có trong bảng users 100 người dùng để tạo một danh sách có thể phân trang.
2. Tạo API thao tác với dữ liệu
Tạo ra một route trong routers/api.php:
Route::get('/users', 'UserController@index');
Tạo UserController với php artisan make:controller UserController và thêm vào phương thức index() như sau:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class UserController extends Controller
{
public function index() {
$users = User::paginate(5);
return response()->json($users);
}
}
Ok, như vậy chúng ta đã thực hiện tạo xong API, thử đăng nhập http://pagination.dev/api/users xem dữ liệu ra đã ổn chưa:
3. Tạo trang master Vue.js
Phần backend như vậy đã xong, chúng ta chuyển sang phần fontend sử dụng Vue.js. Trong ứng dụng mẫu Laravel đã có sẵn một ứng dụng mẫu Vue.js, do vậy chúng ta chỉ cần sửa đổi lại resources/assets/js/components/Example.vue:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Ví dụ về Phân trang với Laravel 5.4 và Vue.js 2</div>
<div class="panel-body">
Hiển thị danh sách người dùng ở đây.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
users: []
}
},
mounted() {
axios.get('http://pagination.dev/api/users')
.then((response) => {
this.users = response.data
})
}
}
</script>
Tiếp đến, thiết lập view resources/views/welcome.blade.php là view mặc định của Laravel:
<html lang="vi VN">
<head>
<meta charset="utf-8">
<title>Phân trang trong project Laravel + Vue.js - Allaravel.com</title>
<!-- Main styles for this application -->
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
<meta id="csrf-token" name="csrf-token" value="{{ csrf_token() }}">
</head>
<body>
<div id="app">
<example></example>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Chạy thử và dùng Vue DevTools chúng ta thấy dữ liệu đã được lấy từ API tạo ra ở mục 2.
4. Xử lý phân trang trong Vue.js
Từ nãy đến giờ chủ yếu là phần chuẩn bị, bây giờ chúng ta mới đi vào phần chính là tạo ra danh sách người dùng có phân trang. Đầu tiên chúng ta tạo ra User.vue trong resources/assets/js/components để hiển thị từng người dùng:
<template>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title" v-text="user.name"></h3>
</div>
<div class="panel-body">
<p v-text="user.email"></p>
</div>
</div>
</template>
<script>
export default {
props: ['user']
}
</script>
Tiếp đó, sử dụng component User.vue trong Example.vue để hiển thị danh sách người dùng:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Ví dụ về Phân trang với Laravel 5.4 và Vue.js 2</div>
<div class="panel-body">
<user v-for="user in users" :user="user" :key="user.id"></user>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import User from './User'
export default {
components: { User },
data () {
return {
users: []
}
},
mounted() {
axios.get('http://pagination.dev/api/users')
.then((response) => {
this.users = response.data.data
})
}
}
</script>
Xem lại http://pagination.dev chúng ta sẽ thấy danh sách người dùng như sau:
Tiếp theo, chúng ta đến phần phân trang, chúng ta tạo ra một component chuyên cho phần phân trang trong resources/assets/js/components/Pagination.vue:
<template>
<nav>
<ul class="pagination">
<li v-if="pagination.current_page > 1">
<a href="#" 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="#" v-on:click.prevent="changePage(page)">{{ page }}</a>
</li>
<li v-if="pagination.current_page < pagination.last_page">
<a href="#" aria-label="Next" v-on:click.prevent="changePage(pagination.current_page + 1)">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</template>
<script>
export default{
props: {
pagination: {
type: Object,
required: true
},
offset: {
type: Number,
default: 4
}
},
computed: {
pagesNumber: function () {
if (!this.pagination.to) {
return [];
}
var from = this.pagination.current_page - this.offset;
if (from < 1) {
from = 1;
}
var to = from + (this.offset * 2);
if (to >= this.pagination.last_page) {
to = this.pagination.last_page;
}
var pagesArray = [];
for (from = 1; from <= to; from++) {
pagesArray.push(from);
}
return pagesArray;
}
},
methods : {
changePage: function (page) {
this.pagination.current_page = page;
}
}
}
</script>
Để sử dụng component này trong Example.vue chúng ta sẽ thay đổi lại mã nguồn chút:
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Ví dụ về Phân trang với Laravel 5.4 và Vue.js 2</div>
<div class="panel-body">
<user v-for="user in users" :user="user" :key="user.id"></user>
</div>
<pagination v-bind:pagination="pagination" v-on:click.native="getUsers(pagination.current_page)" :offset="4"></pagination>
</div>
</div>
</div>
</div>
</template>
<script>
import User from './User'
import Pagination from './Pagination'
export default {
components: { User, Pagination },
data () {
return {
users: [],
counter: 0,
pagination: {
total: 0,
per_page: 2,
from: 1,
to: 0,
current_page: 1
},
offset: 4
}
},
mounted() {
this.getUsers(this.pagination.current_page);
},
methods: {
getUsers (page) {
axios.get('http://pagination.dev/api/users?page='+page)
.then((response) => {
this.users = response.data.data
this.pagination = response.data
})
}
}
}
</script>
Thử lại http://pagination.dev xem phân trang thế nào.
5. Lời kết
Như vậy, chúng ta đã thực hiện xong phần phân trang, nếu bạn muốn style hoặc tạo ra các phân trang riêng thì chúng ta nên xây dựng từ đầu. Nếu bạn muốn sử dụng nhanh một phân trang, chúng ta có thể cài đặt một thư viện phân trang có sẵn ví dụ như:
CÁC BÀI VIẾT KHÁC
0 Bình luận trong "Xây dựng Component phân trang trong Laravel và Vue.js"