Sử dụng song song Vue Router trong Laravel
Xin chào các bạn, trong bài viết này mình sẽ giới thiệu về cách sử dụng Vue Router trong dự án Laravel. Ở đây này mình sử dụng Vue 3 cùng Laravel 8, mọi người có thể tham khảo lại bài viết về cách tích hợp tại đây.
1. Cài đặt Vue Router
Đầu tiên chúng ta cài đặt Vue Router qua câu lệnh terminal sau.
npm install --save vue-router@next
Kiểm tra lại file package.json
ta được như sau.
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"vue-loader": "^16.8.3"
},
"dependencies": {
"vue": "^3.2.23",
"vue-router": "^4.0.12"
}
}
2. Điều hướng lại web-pages routes của Laravel
Ở đây, mình dùng một file blade duy nhất để mount Vue App vào, và giao phó toàn bộ Vue Router để điều hướng web page. Laravel chỉ sử dụng các phần api routes để trả dữ liệu. Vì vậy mình sẽ chỉnh lại file routes\web.php
của Laravel để điều hướng về một view duy nhất như sau.
<?php
use Illuminate\Support\Facades\Route;
Route::get('/{any}', function () {
return view('welcome');
})->where('any', '^(?!api\/)[\/\w\.-]*');
3. Chuẩn bị bên Laravel
Chúng vào Laravel Tinker để fake dữ liệu bằng câu lệnh sau.
User::factory()->count(10)->create();
Sau đó tạo app\Http\Controllers\Api\UserController.php
như sau
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\User;
class UserController extends Controller
{
public function index()
{
return response()->json(User::all(['id', 'name']));
}
public function show(User $user)
{
return response()->json($user);
}
}
Tiếp theo khai báo API route trong file routes\web.php
<?php
use App\Http\Controllers\Api\UserController;
use Illuminate\Support\Facades\Route;
Route::apiResource('users', UserController::class)->only(['index', 'show']);
Ở trong file resources\views\welcome.blade.php
ta sẽ cho Vue App mount vào như sau.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
</head>
<body>
<div id="app"></div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
4. Chuẩn bị bên Vue
Trong file resources\js\app.js
chúng ta sẽ khai báo import từ module vue-router
phương thức createRouter
để tạo router, và createWebHistory
để sử dụng chế độ HTML5 history
, như sau đây.
import { createRouter, createWebHistory } from 'vue-router';
Để làm ví dụ, ta sẽ tạo ra 2 component resources\js\components\Index.vue
và resources\js\components\Show.vue
theo thứ tự như dưới.
Trong file resources\js\components\Index.vue
chúng sẽ sử dụng custom component <router-link>
từ Vue Router để trỏ đến route có name là user.show
và param là id
của user từ dữ liệu API của Laravel trả về.
<template>
<ul>
<li v-for="user in users" :key="user.id">
<router-link :to="{ name: 'users.show', params: { id: user.id } }">{{
user.name
}}</router-link>
</li>
</ul>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const users = ref([]);
(async () => {
const response = await axios.get("/api/users");
users.value = response.data;
})();
return { users };
},
};
</script>
<template>
<ul>
<li>Name: {{ user.name }}</li>
<li>Email: {{ user.email }}</li>
</ul>
</template>
<script>
import { reactive } from "vue";
import { useRoute } from "vue-router";
export default {
setup() {
const route = useRoute();
const user = reactive({
name: "",
email: "",
});
(async () => {
const response = await axios.get(`/api/users/${route.params.id}`);
user.name = response.data.name;
user.email = response.data.email;
})();
return { user };
},
};
</script>
Khai báo import 2 component vừa tạo vào file resources\js\app.js
import Index from './components/Index.vue';
import Show from './components/Show.vue';
Tiếp đó, ta tạo router với cấu hình các route định tuyến đến các components như sau.
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', name: 'users.index', component: Index },
{ path: '/:id', name: 'users.show', component: Show }
]
});
Ta sẽ tạo ra Vue App với template có chứa <router-view />
từ Vue Router để render ra component tương ứng với route đã chỉ định. Cùng với đó dùng chain method use
để sử dụng biến router đã khai báo ở trên như sau.
createApp({ template: '<router-view />' }).use(router).mount('#app');
File resources\js\app.js
của chúng ta tổng thể cuối cùng sẽ như sau.
require('./bootstrap');
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import Index from './components/Index.vue';
import Show from './components/Show.vue';
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', name: 'users.index', component: Index },
{ path: '/:id', name: 'users.show', component: Show }
]
});
createApp({ template: '<router-view />' }).use(router).mount('#app');
5. Xem lại thành quả
Chúng ta chạy câu lệnh npm run dev để compile asset. Sau đó chạy php artisan serve và vào http://localhost:8000 để xem lại thành quả của mình.