Summer sale! Save 50% on access to our entire library of courses.Join here →

How to add Vue.js to a Laravel application

July 7th, 2024

In this guide, we'll cover step-by-step instructions on how to use Vue.js with Laravel. Once you're done, you'll be able to create components and add them to any of your Blade views.

We'll set up a fresh project for this article with the Laravel installer without any starter kit. Go ahead and do this now if you're following along.

laravel new laravel-vue

Choose the No starter kit option and any testing framework and database driver.

Start by updating your web.php routes to point to a new home.

Route::get('/', function () {
    return view('home');
});

Create this view on the command line.

php artisan make:view home

Next, create a base layout. We'll use this Blade component as the wrapper for all of our pages.

php artisan make:component Layouts\\App --view

Once this component is created, wrap the contents of home.blade.php in the layout.

<x-layouts.app>
    Home
</x-layouts.app>

Finally, give the base layout (layouts/app.blade.php) some structure and pull in the default $slot. This injects all content within the x-layouts.app component.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>{{ config('app.name') }}</title>
</head>
<body>
    {{ $slot }}
</body>
</html>

Open up the homepage of your application in the browser, and you should see the home content now wrapped in this layout.

This might seem like a lot of work, but the base layout is important. It'll be where we mount Vue, so any pages you now create and use the base layout for, you'll be able to add Vue components.

Laravel uses Vite as a build tool for JavaScript, so we'll need to install Vue (of course) and the @vitejs/plugin-vue package.

Install both of these first.

npm i vue @vitejs/plugin-vue

Now head over to resources/js/app.js and update it to create and mount a Vue app.

import './bootstrap';

import { createApp } from 'vue'

const app = createApp({})

app.mount('#app')

So where are we mounting Vue to? Well, head back to layouts/app.blade.php and add an element with an app ID.

<body>
    <div id="app">
        {{ $slot }}
    </div>
</body>

Our Vite config (vite.config.js) needs to know how to compile Vue, so update it to look like this.

import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],

    resolve: {
        alias: {
            vue: 'vue/dist/vue.esm-bundler.js',
        },
    },
})

We now need to include the Vite-built assets in our layout file.

Head over to layouts/app.blade.php once again, and add the @vite directive in the head of the layout.

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  	<meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>{{ config('app.name') }}</title>

    @vite(['resources/js/app.js', 'resources/css/app.css'])
</head>

Once that's done, run npm run dev.

npm run dev

If you don't see any errors here, it's time to start creating Vue components!

Let's create a simple component to check everything is working. You can put this anywhere, but inside the resources/js/Components directory makes sense.

Create Counter.vue there.

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
{{ count }} <button v-on:click="count++">Increment</button>
</template>

We'll need to register this component to render it on the homepage. In resources/app.js, register it like this:

import './bootstrap';

import { createApp } from 'vue'
import Counter from './Components/Counter.vue'

const app = createApp({})

app.component('Counter', Counter)

app.mount('#app')

The moment of truth is here! Add the Counter component to your home.blade.php file.

<x-layouts.app>
    <Counter />
</x-layouts.app>

In your browser, you should now have a fully working Vue component. Repeat the same steps to add more components!

Thanks for reading! If you found this article helpful, you might enjoy our practical screencasts too.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first to leave a comment.