In this section, we will connect a Laravel backend REST API with a Vue 3 frontend using Axios. We will utilize the Vue 3 Composition API and the new <script setup>
syntax in Vue.js.
Setup Laravel Backend Api
Install fresh laravel app and connect to database.
composer create-project laravel/laravel laravel-backend
Create User Fake Data
database/DatabaseSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
\App\Models\User::factory(10)->create();
}
}
run migration with seeder.
php artisan migrate:fresh --seed
Create User Api Controller routes and Resource
Run below command to create user user controller.
php artisan make:controller Api/UserController
Create user resource for format api.
php artisan make:resource UserResource
Add necessary data in user resource.
app/Http/Resources/UserResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at,
];
}
}
Next you need to add user resource in api user controller.
app/Http/Controllers/Api/UserController.php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Resources\UserResource;
use App\Models\User;
class UserController extends Controller
{
public function index()
{
$users = User::paginate(10);
return UserResource::collection($users);
}
}
Create user api route.
routes/api.php
<?php
use App\Http\Controllers\Api\UserController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('/users', [UserController::class, 'index']);
Serve laravel app.
php artisan serve
Test User Api In PostMan Tool
http://localhost:8000/api/users
Laravel Backend Api Connect with Frontend Vue 3
Create vue 3 project.
npm init vue@latest
Select your requirements.
Vue.js - The Progressive JavaScript Framework
✔ Project name: … frontend
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit Testing? … No / Yes
✔ Add Cypress for both Unit and End-to-End testing? … No / Yes
✔ Add ESLint for code quality? … No / Yes
✔ Add Prettier for code formatting? … No / Yes
Scaffolding project in /vue-project/frontend...
Done. Now run:
cd frontend
npm install
npm run dev
Install axios In Vue 3
Run below command to install vue-axios.
npm i vue-axios
Next, you need to install Tailwind CSS in Vue 3. You can refer to the documentation for detailed instructions.
Set Axios Path in Vue 3
Setup Api path in main.js using axios.
src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './index.css'
import axios from 'axios'
axios.defaults.baseURL = 'http://localhost:8000/api/';
const app = createApp(App)
app.use(router)
app.mount('#app')
Fetch Laravel Api in Vue 3 Using Axios
Fetch laravel backend data using vue 3 composition api.
src/views/HomeView.vue
<script>
import axios from 'axios';
import { onMounted, ref } from 'vue';
export default {
setup() {
// reactive state
let users = ref([]);
// mounted
onMounted(() => {
// get api from laravel backend
axios
.get('/users')
.then((res) => {
// assign state users with response data
users.value = res.data.data;
})
.catch((error) => {
console.log(error.res.data);
});
});
return {
users
};
},
};
</script>
<template>
<main class="container flex items-center justify-center h-screen mx-auto">
<div class="flex flex-col">
<div class="overflow-x-auto">
<div class="p-1.5 w-full inline-block align-middle">
<div class="overflow-hidden border rounded-lg">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
ID
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
Name
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
Email
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-center text-gray-500 uppercase"
>
Created At
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr v-for="user in users" :key="user.id">
<td
class="px-6 py-4 text-sm font-medium text-gray-800 whitespace-nowrap"
>
{{ user.id }}
</td>
<td class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap">
{{ user.name }}
</td>
<td class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap">
{{ user.email }}
</td>
<td class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap">
{{ user.created_at }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
</template>
Fetch laravel rest api with vue 3 using script setup.
src/views/HomeView.vue
<script setup>
import axios from 'axios';
import { onMounted, ref } from 'vue';
// reactive state
let users = ref([]);
// mounted
onMounted(async () => {
// get api from laravel backend
await axios
.get('/users')
.then((res) => {
// assign state users with response data
users.value = res.data.data;
})
.catch((error) => {
console.log(error.res.data);
});
});
</script>
<template>
<main class="container flex items-center justify-center h-screen mx-auto">
<div class="flex flex-col">
<div class="overflow-x-auto">
<div class="p-1.5 w-full inline-block align-middle">
<div class="overflow-hidden border rounded-lg">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
ID
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
Name
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-left text-gray-500 uppercase"
>
Email
</th>
<th
scope="col"
class="px-6 py-3 text-xs font-bold text-center text-gray-500 uppercase"
>
Created At
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr v-for="user in users" :key="user.id">
<td
class="px-6 py-4 text-sm font-medium text-gray-800 whitespace-nowrap"
>
{{ user.id }}
</td>
<td class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap">
{{ user.name }}
</td>
<td class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap">
{{ user.email }}
</td>
<td class="px-6 py-4 text-sm text-gray-800 whitespace-nowrap">
{{ user.created_at }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
</template>
You can also use full url with axios.
onMounted(() => {
// get api from laravel backend
axios
.get('http://localhost:8000/api/users')
.then((res) => {
// assign state posts with response data
posts.value = res.data.data;
})
.catch((error) => {
console.log(error.res.data);
});
});
run vue server
npm run dev