Originally published byDev.to
We can use inertia.js, but sometimes we just need to keep it simple. This also works for React and others.
Folder Structure
# only an example
resources
├ js
│ ├ app.js
│ ├ App.vue
│ ├ pages
│ │ └ Dashboard.vue
│ ├ components
│ │ └ ui
│ └ layouts
└ views
└ app.blade.php
# Flow
Laravel route
↓
controller returns Blade
↓
Blade sets PAGE + PROPS
↓
Vue loads correct page component
↓
component receives props
Steps
- Installation
# laravel
laravel new example-app
# vue
npm install vue
npm install @vitejs/plugin-vue --save-dev
- Vite
# vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
vue(),
],
});
- Entry
# resources\js\app.js
import { createApp, h } from "vue"
import App from "./App.vue"
const app = createApp({
render: () => h(App, {
page: window.PAGE,
props: window.PROPS
})
})
app.mount("#vue-app")
- Root
# resources\js\App.vue
<script setup>
import { defineAsyncComponent } from "vue"
import AppSidebar from "./components/app-sidebar.vue"
const props = defineProps({
page: String,
props: Object
})
const pages = import.meta.glob("./pages/**/*.vue")
const loader = pages[`./pages/${props.page}.vue`]
const PageComponent = loader ? defineAsyncComponent(loader) : null
</script>
<template>
<div class="flex min-h-screen">
<AppSidebar />
<main class="flex-1 p-6">
<component v-if="PageComponent" :is="PageComponent" v-bind="props.props" />
<div v-else>Page not found</div>
</main>
</div>
</template>
- Connect
# resources\views\layouts\app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name') }}</title>
<script>
window.PAGE = @json($page);
window.PROPS = @json($props);
window._USER = @json(auth()->user());
window.APP_NAME = @json(config('app.name'));
</script>
@vite(['resources/js/app.js'])
</head>
<body>
<div id="vue-app"></div>
</body>
</html>
- Run
# start your web server, and then:
npm run dev
- Controller
# example
public function index()
{
return view('app', [
'page' => 'componentsname',
'props' => [
'title' => 'page title',
'constant' => ['type' => 'monthly']
]
]);
}
Need help building your app? I’m available for freelance web & Android development — raflizocky.netlify.app
☕ Support my writing: paypal.me/raflizocky · saweria.co/raflizocky
🇺🇸
More news from United StatesUnited States
NORTH AMERICA
Related News
How Braze’s CTO is rethinking engineering for the agentic area
11h ago
Amazon Employees Are 'Tokenmaxxing' Due To Pressure To Use AI Tools
22h ago
KDE Receives $1.4 Million Investment From Sovereign Tech Fund
2h ago
Instagram’s new ‘Instants’ feature combines elements from Snapchat and BeReal
2h ago
Six Claude Code Skills That Close the AI Agent Feedback Loop
2h ago