Integrating Vue.js Components in Laravel: A Beginner’s Guide
Laravel and Vue.js are two powerful frameworks commonly used in web development. Laravel provides a comprehensive backend solution, while Vue.js offers a flexible and efficient way to build interactive frontend components. Although Laravel offers alternative options like Inertia.js and Livewire for dynamic interfaces, there are situations where developers prefer to integrate Vue.js directly into their Laravel applications, particularly for existing or beginner projects.
This tutorial is specifically designed for beginners who are starting with such projects and want to learn how to seamlessly integrate Vue.js components into Laravel applications. By following the steps outlined in this tutorial, you will acquire valuable skills in incorporating Vue.js components into your Laravel projects, even if they were initially built without Vue.js. Let’s dive in and discover how you can enhance your Laravel development skills by leveraging the power of Vue.js!
Prerequisites: Before getting started, ensure that you have the following:
- Basic knowledge of the Laravel framework
- Familiarity with Vue.js fundamentals
Step 1: Setting Up Laravel
To begin, make sure you have Laravel installed on your local machine. If not, follow the official Laravel documentation to install Laravel and set up a new project. Once your Laravel project is ready, navigate to the project directory in your terminal.
Step 2: Installing Laravel Breeze
Laravel Breeze is a lightweight scaffolding package that provides a minimal setup for authentication in Laravel applications. To install Laravel Breeze, run the following command in your terminal:
composer require laravel/breeze --dev
Once installed, generate the authentication scaffolding by running the following command:
php artisan breeze:install
Step 3: Creating the Database
Next, create a new database for your Laravel application. You can use a database management tool like phpMyAdmin or run the appropriate SQL commands in your database server.
Step 4: Running Migrations
Now, run the database migrations to set up the necessary tables for authentication and user management. Execute the following command in your terminal:
php artisan migrate
Step 5: Installing Dependencies and Building Assets
To install the necessary frontend dependencies and build the assets, run the following commands:
npm install
npm run dev
Step 6: Serving the Laravel Application
To serve your Laravel application locally, run the following command:
php artisan serve
This will start a local development server, and you can access your application in your web browser using the provided URL.
Step 7: Installing Vue.js and Vue Loader
To enhance the development experience when working with Vue.js components, we’ll install Vue Loader. Vue Loader is the Webpack loader that enables writing single-file Vue components. It simplifies the component structure by combining HTML, CSS, and JavaScript in a single file.
To install Vue Loader, run the following command:
npm install vue@next vue-loader@next
Step 8: Installing Vue.js Plugin for Vite
Vite is a next-generation front-end build tool, and Laravel provides a plugin to integrate it with your Laravel application. Install the Vue.js plugin for Vite by running the following command:
npm i @vitejs/plugin-vue
Step 9: Updating the Vite Configuration
To configure Vite, open the vite.config.js
file and update it with the following code:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
],
resolve: {
alias: {
'@': '/resources/js',
'vue': 'vue/dist/vue.esm-bundler.js'
},
},
});
Step 10: Updating the app.js File
Open the app.js
file and update it as follows:
import './bootstrap';
import { createApp } from 'vue';
const app = createApp({});
app.mount("#app");
Step 11: Modifying Blade Templates
To make Vue.js components work with Laravel’s Blade templating engine, you need to make a few modifications to the blade files. Open the app.blade.php
and guest.blade.php
files and add id="app"
to their parent elements.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap">
<!-- Scripts -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="font-sans antialiased">
<div class="min-h-screen bg-gray-100" id="app">
....
....
....
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap">
<!-- Scripts -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="font-sans text-gray-900 antialiased">
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100" id="app">
....
....
....
Step 12: Creating Vue.js Components
Create a new folder named “components” inside the resources/js
directory. Inside the "components" folder, create a Vue.js component file, such as ComponentA.vue
, and define the component's template and logic. For example:
<template>
<h1>Working</h1>
</template>
Step 13: Registering Vue.js Components
Open the app.js
file and import the created Vue.js component. Register the component using the app.component
method. For example:
import './bootstrap';
import { createApp } from 'vue';
import ComponentA from './components/ComponentA.vue';
const app = createApp({});
app.component('ComponentA', ComponentA);
app.mount("#app");
Step 14: Using Vue.js Components in Blade Templates
With the Vue.js component registered, you can now use it in your Blade templates. Open any Blade file and add the component using the <component-a></component-a>
syntax. Make sure to include the component within the <div id="app"></div>
element.
Another Component and Fetching Data from the Laravel
To demonstrate fetching data from the database, let’s create another component called ComponentB.vue in the components directory. You can write any code you want inside this component. Register it in the app.js file, similar to how we registered the first component (ComponentA).
import './bootstrap';
import { createApp } from 'vue';
import ComponentA from './components/ComponentA.vue';
import componentB from './components/ComponentB.vue';
const app = createApp({});
app
.component('ComponentA', ComponentA)
.component('ComponentB', ComponentB);
app.mount("#app");
Sending Data from the Blade File to the Vue Component
To send data from the Laravel blade file to the Vue component, we’ll pass the User object to the ComponentA.vue component. Open the ComponentA.vue file and make the following changes:
<script setup>
const props = defineProps({
user: Object
});
</script>
<template>
<h1>Hello, {{ user.name }}</h1>
</template>
Now, you can send the data to ComponentA using the <component-a>
tag. Let's update the dashboard.blade.php file as follows:
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<component-a :user="{{ Auth::user() }}"/>
</div>
</div>
</div>
</div>
</x-app-layout>
Now, when you reload the page, it will display the logged-in user’s name in the ComponentA.
Fetching Data from the Database
To fetch data from the database in the Vue component, we’ll use the Axios package. Install Axios by running the following command:
npm install axios
Since we are integrating Vue.js components within a Blade template and need to access session information and other web-specific features, we’ll create a route in the web.php
file.
In Laravel, the web.php
the file is specifically used for handling web-related routes and interactions that require session management, cookie handling, CSRF protection, and other web-specific functionalities.
By defining the route in web.php
, we ensure that our Vue component can access session data and other web-related features when making HTTP requests or interacting with the backend.
In our example, we’ll create a simple route to demonstrate fetching data from the server. Add the following route to your web.php
file:
Route::get('/demo-request', function() {
return response()->json(Auth::user());
});
This route will respond to GET requests made to the /demo-request
URL. In this case, we're returning the authenticated user's data as a JSON response.
By using web.php
instead of api.php
, we ensure that the route has access to session information, cookies, and other web-related features that may be required in our Vue component.
Now, let’s update the ComponentA.vue file to fetch the data using Axios:
<script setup>
import axios from 'axios';
import { ref } from 'vue';
const user = ref();
async function sendRequest() {
const response = await axios.get('/demo-request')
if (response.status === 200) {
user.value = response.data;
}
}
</script>
<template>
<h1>Hello, {{ user ? user.name : 'World' }}</h1>
<button class="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150" @click="sendRequest">Send Request</button>
</template>
In this updated component, we have added a button that triggers the sendRequest
function when clicked. It uses Axios to make a GET request to the /demo-request
route we created earlier. The response data is then assigned to the user
ref.
Now, the component will display “Hello, World” by default. Clicking the button will change the text to “Hello, User Name” once the data is fetched from the database.
You can also use Axios to handle POST requests and perform other API operations within your Vue components.
Sending a POST Request and CSRF Token
To handle a POST request and include the CSRF token, follow these steps:
- In your
web.php
file, create a new route for the POST request:
Route::post('/demo-post', function (Request $request) {
// Validate the request data if needed
// Perform some processing with the data
// Return a response
return response()->json(['message' => 'Post request successful']);
});
2. In your Blade template, add the CSRF token to the <head>
section of the layout file:
<head>
<!-- Other meta tags and stylesheets -->
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
When working with Laravel’s web.php
file, which has built-in CSRF (Cross-Site Request Forgery) protection, it's important to include the CSRF token in the <head>
tag of your Blade template. This is necessary to ensure secure communication between your application and the server. Without the CSRF token, the request will fail.
3. In your Vue.js component, use the Axios package to handle the POST request:
import axios from 'axios';
async function submitData() {
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
try {
const response = await axios.post('/demo-post', { data }, {
headers: {
'X-CSRF-TOKEN': csrfToken,
},
});
// Handle the response
} catch (error) {
// Handle errors
}
}
Remember to adjust the route, form fields, and data handling code according to your specific application’s requirements.
That’s it! You have now learned how to send a POST request with the CSRF token in a Vue.js component within a Laravel application.
When working with Laravel and Vue.js, you have the option to enhance your development experience by utilizing additional packages. One such package is robsontenorio/vue-api-query
, which offers compatibility with spatie/laravel-query-builder
. By incorporating this package, you can simplify API query building in your Vue.js applications. Exploring these tools and staying updated with the Laravel ecosystem allows you to optimize your development workflow and take advantage of new possibilities. Happy coding!