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!