How to use multiple Vue 3 components in blade template (non spa)
Hi,
I am building a website (Laravel/vue/vite) that i wish to use a mix of blade and Vue 3 components. What is the best way to do this, as in how do i set this up? and include the vue 3 components in my website?
For example i might have home.blade.php which i have normal blade and php in but then half way down the file i want an ajax sign up form that's built in vue 3 then some more blade then a button component built in Vue 3. I would also have for example a contact page that is made with a different blade template that i might want to include other (or the same) Vue components in.
I understand that in an spa you normally have a entry point for id="app" but that wouldn't work for my needs.
To use multiple Vue 3 components in a non-SPA (Single Page Application) Laravel Blade template, you can follow these steps:
Install Vue 3 and Vite: If you haven't already, make sure Vue 3 and Vite are installed in your Laravel project. You can use Laravel's built-in Vite support or set it up manually.
Create Vue Components: Create your Vue components as you normally would. For example, create SignUpForm.vue and ButtonComponent.vue files in your resources/js/components directory.
Register Components Globally or Locally: You can register your components globally in your app.js file, or you can import them locally in a specific entry file for the page where you want to use them.
Global Registration Example:
import { createApp } from 'vue';
import SignUpForm from './components/SignUpForm.vue';
import ButtonComponent from './components/ButtonComponent.vue';
const app = createApp({});
app.component('sign-up-form', SignUpForm);
app.component('button-component', ButtonComponent);
app.mount('#app');
Local Registration Example:
import { createApp } from 'vue';
import SignUpForm from './components/SignUpForm.vue';
import ButtonComponent from './components/ButtonComponent.vue';
const app = createApp({});
// Only register the components needed on this page
app.component('sign-up-form', SignUpForm);
app.component('button-component', ButtonComponent);
app.mount('#specific-page');
Include Vue Components in Blade Template: In your Blade template, you can now include Vue components wherever you need them by using their tags. Make sure to wrap your components with a div that has an id that matches the one you used in app.mount().
Example Blade Template (home.blade.php):
<div>
<!-- Blade and PHP content -->
</div>
<div id="app">
<!-- Vue 3 component -->
<sign-up-form></sign-up-form>
</div>
<div>
<!-- More Blade and PHP content -->
</div>
<div id="app">
<!-- Another Vue 3 component -->
<button-component></button-component>
</div>
Compile Your Assets: Use Vite to compile your assets. If you're using Laravel's built-in Vite support, you can run npm run dev or npm run build to compile your assets for development or production, respectively.
Include the Compiled JS: In your Blade layout or specific templates, include the compiled JavaScript file generated by Vite.
Example Blade Layout:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Head Contents -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<!-- Body Contents -->
</body>
</html>
By following these steps, you can include multiple Vue 3 components in your Blade templates without creating a SPA. Each component will be initialized within its own context, allowing you to sprinkle Vue components throughout your Blade templates as needed.
@thetalker85 Yes. It’s basically a container that Vue will be “active” within. So if you reference Vue components with that mark-up, then it will be rendered as that corresponding Vue component.
If you have HTML mark-up that you 100% know won’t contain any Vue components, then you can use the v-pre directive to tell Vue to skip checking that DOM element for any components:
<!-- resources/views/contact.blade.php -->
<main v-pre>
<!-- Nothing inside this element will be treated as Vue component -->
<!-- So foo-component will be just be left as is -->
<h1>Contact</h1>
<!-- Contact page content -->
<foo-component></foo-compnent>
</main>
<aside>
<!-- Element does NOT have v-pre directive -->
<!-- So components inside here WILL be parsed -->
<bar-component></bar-component>
</aside>
It’s best to put the <div id="app"> wrapping element in some form of layout template, like I did in my example, as then you don’t have to remember to add it to each and every Blade view that you want to include a Vue component.