Forum dạng SPA với Laravel và Vue.js – Phần 2: Cơ bản về routing
NỘI DUNG BÀI VIẾT
Trong phần trước, chúng ta đã xây dựng xong khung dự án sử dụng cả Laravel và Vue.js, tiếp theo là các công việc khác, nó giúp hình thành dần dần ứng dụng Forum dạng ứng dụng đơn trang. Laravel cho phép tạo một master page để từ đó chúng ta có thể xây dựng các trang khác, với Vue.js và vue-router cũng vậy, chúng ta tạo ra một master view là App.Vue để từ đó có thể mở rộng ra các view (các Vue.component) khác.
1. Thiết kế master view App.vue
1.1 Tạo view chính App.vue
App.vue là khung chính cho view, từ đây có thể mở rộng ra các view khác trong ứng dụng, tạo file resources/assets/js/components/App.Vue với nội dung sau:
<template>
<div id="root">
<h1>
SPA-FORUM <small> với Laravel + Vue.js</small>
</h1>
<router-view></router-view>
</div>
</template>
Code language: HTML, XML (xml)
Trong App.vue, thẻ là rất quan trọng nó nói với Vue.js rằng chỗ này sẽ được Vue-router xử lý và đưa vào các nội dung là các component tùy thuộc vào đường dẫn. Nó cũng giống như khi bạn làm việc với @yield trong Laravel template.
1.2 Thiết lập điểm bắt đầu của Vue.js
Nơi bắt đầu của Vue.js chính là resources/assets/js/app.js, thay đổi code như sau:
require('./bootstrap');
import Vue from 'vue';
import App from './components/App';
var vm = new Vue({
el: '#app',
render: h => h(App)
})
Code language: JavaScript (javascript)
Một số chú ý, require(‘./bootstrap’) là để tải file bootstrap.js, nội dung file này nhằm tải vào ứng dụng các thư viện cần thiết như jQuery, bootstrap sass, axios và thiết lập CSRF-Token một khái niệm trong Laravel. Tiếp đến là nó tải vào App component là master view cho ứng dụng, sau đó đến router là nơi thiết lập việc mapping giữa đường dẫn và các component để thực hiện render nội dung. ### 1.3 Thiết lập view mặc định của Laravel
Mọi ứng dụng Laravel đều được thiết lập đường dẫn trang chủ mapping với view resources/views/welcome.blade.php, chúng ta cần thay đổi nội dung view này để nó dùng các tài nguyên javascript, css đã được biên dịch.
<html lang="vi VN">
<head>
<meta charset="utf-8">
<title>SPA Forum - 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"></div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Code language: HTML, XML (xml)
Ok, như vậy chúng ta đã thiết lập xong trang chính của dự án, chúng ta thử vào xem thế nào nhé. Nhớ chạy npm run watch để thực hiện biên dịch tài nguyên Javascript và CSS tự động ngay cả khi có thay đổi. Bạn chưa hiểu chỗ này xem thêm cách sử dụng Laravel Mix. Chú ý, để nguyên màn hình console này đừng tắt đi vì nó đang chạy liên tục.

Ok, giờ chúng ta vào thử http://spa-forum.dev xem thế nào.

2. Xây dựng nội dung con trong ứng dụng SPA-Forum
SPA-Forum đã có trang master, trong ứng dụng đa trang chúng ta có các trang khác nhau, với SPA các trang khác nhau là các nội dung khác nhau hay còn gọi là nội dung con. Chúng ta sẽ thực hiện xây dựng các nội dung con cho Category, Topic.
2.1 Cài đặt vue-router
Vue-router là gói thư viện giúp thực hiện tạo ra các nội dung bằng cách map giữa đường dẫn và các Vue component. (Tham khảo chi tiết về Vue-router). Thực hiện cài đặt gói Vue-router, do gói này không có trong thiết lập mặc định của Laravel Mix bằng lệnh npm install vue-router –save.
c:\xampp\htdocs\spa-forum>npm install vue-router --save
c:\xampp\htdocs\spa-forum
`-- vue-router@2.5.3
Code language: CSS (css)
2.2 Xây dựng file mapping route
Thực tạo đưa hết các mapping giữa đường dẫn và Vue component vào file resources/assets/js/routes/index.js như sau:
import Vue from 'vue'
import Router from 'vue-router'
// Views
import HomeView from '../components/views/HomeView'
import CategoryView from '../components/views/CategoryView'
import TopicView from '../components/views/TopicView'
Vue.use(Router)
export default new Router({
routes: [
{ path: '/', name: 'Home', component: HomeView },
{ path: '/category', name: 'Category', component: CategoryView },
{ path: '/topic', name: 'Topci', component: TopicView }
]
})
Code language: JavaScript (javascript)
Trong này có một số chú ý, cần import Vue-router vào và sử dụng lệnh Vue.user(VueRouter) không sẽ bị lỗi hoặc không hoạt động được.
2.3 Tạo các Component cho nội dung con
Trong file mapping route đã có khai báo các component cho nội dung con chúng ta thực hiện tạo các component này trong resources/assets/js/components/views: HomeView.vue
<template>
<div>
Trang chủ
</div>
</template>
Code language: HTML, XML (xml)
CategoryView.vue
<template>
<div>
Trang Category
</div>
</template>
Code language: HTML, XML (xml)
TopicView.vue
<template>
<div>
Trang Topic
</div>
</template>
Code language: HTML, XML (xml)
Chúng ta thử thực hiện vào
Sẽ thấy các kết quả như sau:

3. Chế độ routing HTML5 history
Mặc định, vue-router sử dụng chế độ routing là hash, các đường dẫn sẽ có dạng http://spa-forum.dev/#/topic, http://spa-forum.dev/#/category… Vue-router cũng có một chế độ routing khác là HTML5 history, nó sử dụng history.pushState API để điều hướng các URL mà không cần tải lại trang. Do đó các đường dẫn trở lại về dạng như bình thường là http://spa-forum.dev/topic, http://spa-forum.dev/category. Chỉ cần thêm mode:’history’ vào trong phần khai báo router là xong. Tuy nhiên, chúng ta sẽ gặp phải một vấn đề là khi thực thi http://spa-forum.dev/topic sẽ gặp lỗi như sau:

Lỗi này do chúng ta chưa thiết lập các route của Laravel do khi chạy đường dẫn này thì máy chủ web Apache hoặc NginX sẽ đón nhận và xử lý routes/web.php mà hiện tại trong đây mới chỉ thiết lập đường dẫn trang chủ:
Route::get('/', function () {
return view('welcome');
});
Code language: PHP (php)
Để xử lý vấn đề này, chúng ta sẽ thiết lập để Laravel lắng nghe tất cả các request và định tuyến nó đến view welcome như sau:
Route::any('{all}', function () {
return view('welcome');
})
->where(['all' => '.*']);
Code language: PHP (php)
và nhường việc xử lý đường dẫn lại cho vue-router. Việc tiếp theo là chúng ta cần thiết lập mode history cho vue-router trong router/index.js:
import Vue from 'vue'
import Router from 'vue-router'
// Views
import HomeView from '../components/views/HomeView'
import CategoryView from '../components/views/CategoryView'
import TopicView from '../components/views/TopicView'
Vue.use(Router)
export default new Router({
routes: [
{ path: '/', name: 'Home', component: HomeView },
{ path: '/category', name: 'Category', component: CategoryView },
{ path: '/topic', name: 'Topci', component: TopicView }
],
mode: 'history'
})
Code language: JavaScript (javascript)
4. Xử lý lỗi 404 trong Vue-router
Trong quá trình website vận hành, có nhiều đường link được copy từ website và dán vào đâu đó trên mạng như vào Facebook, vào các diễn đàn, vào các bài viết trong các trang tin… quá trình này có thể xảy ra lỗi copy không đầy đủ, dẫn đến các đường link không chạy được hoặc trang không tìm thấy. Các lỗi này gọi chung là lỗi 404 không tìm thấy trang web yêu cầu, trước đây chúng ta thường xử lý trong Laravel thông qua view được cài đặt sẵn là resources/views/error/404.blade.php. Lỗi 404 cũng có thể xử lý trong Vue-router rất đơn giản bằng cách thêm route sau vào routes/index.js
{ path: '*', component: NotFound }
Code language: CSS (css)
Như vậy, khi xử lý qua các đường dẫn nếu đến cuối cùng mà vẫn không map được với component nào nó sẽ map với component NotFound.vue, chúng ta tạo ra một component NotFound.vue trong resources/components với nội dung tạm như sau:
<template>
<div>
Lỗi 404: Không tìm thấy trang yêu cầu
</div>
</template>
Code language: HTML, XML (xml)
Khi đó chúng ta thử thực hiện một đường dẫn ngẫu nhiên nào đó xem thế nào, ví dụ http://spa-forum.dev/tin-tuc/laravel-5-5-chuan-bi-ra-mat-trong-thang-7

Hoặc nếu bạn không thích tạo ra trang 404 thì bạn có thể chuyển hướng tất cả các trang không tồn tại về một trang nào đấy cũng được, ví dụ dưới đây chuyển hướng các trang không tìm thấy về trang chủ.
export default new Router({
routes: [
{ path: '/', name: 'home', component: Home},
{ path: '/category', component: Category, name: 'category' },
{ path: '/topic', component: Topic, name: 'topic'}
],
mode: 'history',
redirect: {
'*' : '/'
}
})
Code language: JavaScript (javascript)
5. Tiếp theo sẽ làm gì?
Trong phần Cơ bản về routing này chúng ta đã tiếp tục xây dựng ứng dụng Forum đơn trang bằng Laravel và Vue.js, tóm lược lại các phần chúng ta đã xử lý như sau:
- Xây dựng master view App.vue, làm quen với tạo ra các Vue component và map chúng với các route cụ thể.
- Xử lý đường dẫn như đường dẫn bình thường với chế độ history.
- Xử lý lỗi 404 không tìm thấy trang yêu cầu trong Vue-router.
Trong phần tiếp theo sẽ chuẩn bị các API cho category và topic, tiếp tục làm việc với từng đối tượng cụ thể trong ứng dụng như tạo database, viết các RESTful API mạnh mẽ và nhanh chóng.
Cảm ơn các bạn đã đọc.
Các bạn có thể tham khảo các bài viết hay về Laravel tại đây.
Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.
Nguồn tham khảo: Allaravel
Leave a Reply