Kasir/Documentation/Frontend.md
2025-09-09 11:59:00 +07:00

471 lines
11 KiB
Markdown

# Laravel + Vue.js + Vue Router Setup Guide
Panduan lengkap untuk setup Laravel dengan Vue.js 3, Vue Router, dan Tailwind CSS menggunakan Vite.
## Prerequisites
- PHP >= 8.1
- Composer
- Node.js >= 16.x
- NPM atau Yarn
## Step 1: Instalasi Laravel
```bash
# Buat project Laravel baru
composer create-project laravel/laravel project-name
# Masuk ke directory project
cd project-name
# Setup environment
cp .env.example .env
php artisan key:generate
```
## Step 2: Instalasi Dependencies Frontend
```bash
# Install Vue.js dan dependencies
npm install vue@latest vue-router@latest
# Install Vite plugins
npm install --save-dev @vitejs/plugin-vue
# Install Tailwind CSS
npm install --save-dev tailwindcss@latest @tailwindcss/vite
# Install utilities
npm install --save-dev axios concurrently
```
### Package.json Final
```json
{
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
"scripts": {
"build": "vite build",
"dev": "vite"
},
"devDependencies": {
"@tailwindcss/vite": "^4.0.0",
"@vitejs/plugin-vue": "^6.0.1",
"axios": "^1.11.0",
"concurrently": "^9.0.1",
"laravel-vite-plugin": "^2.0.0",
"tailwindcss": "^4.0.0",
"vite": "^7.0.4"
},
"dependencies": {
"vue": "^3.5.19",
"vue-router": "^4.5.1"
}
}
```
## Step 3: Konfigurasi Vite
Buat/update `vite.config.js`:
```javascript
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import tailwindcss from "@tailwindcss/vite";
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: ["resources/css/app.css", "resources/js/app.js"],
refresh: true,
}),
tailwindcss(),
vue()
],
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
},
},
});
```
## Step 4: Setup Tailwind CSS
Buat `tailwind.config.js`:
```javascript
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
],
theme: {
extend: {},
},
plugins: [],
}
```
Update `resources/css/app.css`:
```css
@import 'tailwindcss';
```
## Step 5: Struktur Folder Frontend
Buat struktur folder berikut di `resources/js/`:
```
resources/js/
├── components/
│ └── App.vue
├── pages/
│ ├── Home.vue
│ ├── About.vue
│ └── Contact.vue
├── router/
│ └── index.js
└── app.js
```
## Step 6: Setup Vue Router
### `resources/js/router/index.js`
```javascript
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../pages/Home.vue'
import About from '../pages/About.vue'
import Contact from '../pages/Contact.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/contact',
name: 'Contact',
component: Contact
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
```
### `resources/js/app.js`
```javascript
import { createApp } from 'vue';
import router from './router';
import App from './components/App.vue';
const app = createApp(App);
app.use(router);
app.mount('#app');
```
## Step 7: Buat Vue Components
### `resources/js/components/App.vue`
```vue
<template>
<div id="app">
<nav class="bg-blue-600 shadow-lg">
<div class="max-w-7xl mx-auto px-4">
<div class="flex justify-between h-16">
<div class="flex space-x-8">
<router-link
to="/"
class="flex items-center px-3 py-2 text-white hover:text-blue-200"
:class="{ 'border-b-2 border-white': $route.name === 'Home' }"
>
Home
</router-link>
<router-link
to="/about"
class="flex items-center px-3 py-2 text-white hover:text-blue-200"
:class="{ 'border-b-2 border-white': $route.name === 'About' }"
>
About
</router-link>
<router-link
to="/contact"
class="flex items-center px-3 py-2 text-white hover:text-blue-200"
:class="{ 'border-b-2 border-white': $route.name === 'Contact' }"
>
Contact
</router-link>
</div>
</div>
</div>
</nav>
<main class="max-w-7xl mx-auto py-6 px-4">
<router-view />
</main>
</div>
</template>
<script setup>
// Main app component
</script>
```
### `resources/js/pages/Home.vue`
```vue
<template>
<div class="home">
<div class="text-center">
<h1 class="text-4xl font-bold text-gray-800 mb-8">Welcome Home</h1>
<div class="bg-yellow-100 border-2 border-yellow-300 rounded-lg p-8 max-w-md mx-auto">
<p class="text-2xl font-bold text-gray-800">{{ message }}</p>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const message = ref("Hello from Vue.js!")
</script>
```
### `resources/js/pages/About.vue`
```vue
<template>
<div class="about">
<h1 class="text-3xl font-bold text-gray-800 mb-6">About Us</h1>
<div class="bg-green-50 border border-green-200 rounded-lg p-6">
<p class="text-lg text-gray-700 mb-4">
This is our about page built with Laravel and Vue.js!
</p>
<button
@click="showMore = !showMore"
class="bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded transition duration-200"
>
{{ showMore ? 'Show Less' : 'Learn More' }}
</button>
<div v-show="showMore" class="mt-4 p-4 bg-white rounded border">
<p class="text-gray-600">
We're passionate about creating amazing web applications using modern technologies
like Laravel, Vue.js, and Tailwind CSS.
</p>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const showMore = ref(false)
</script>
```
### `resources/js/pages/Contact.vue`
```vue
<template>
<div class="contact">
<h1 class="text-3xl font-bold text-gray-800 mb-6">Contact Us</h1>
<div class="max-w-md mx-auto bg-white shadow-md rounded-lg p-6">
<form @submit.prevent="submitForm" class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Name</label>
<input
v-model="form.name"
type="text"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input
v-model="form.email"
type="email"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Message</label>
<textarea
v-model="form.message"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 h-24"
required
></textarea>
</div>
<button
type="submit"
class="w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded transition duration-200"
>
Send Message
</button>
</form>
<div v-if="submitted" class="mt-4 p-3 bg-green-100 border border-green-300 rounded text-green-700">
Thank you for your message!
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
const form = reactive({
name: '',
email: '',
message: ''
})
const submitted = ref(false)
const submitForm = () => {
console.log('Form submitted:', form)
submitted.value = true
// Reset form after 3 seconds
setTimeout(() => {
submitted.value = false
Object.assign(form, { name: '', email: '', message: '' })
}, 3000)
}
</script>
```
## Step 8: Update Laravel Views
### `resources/views/welcome.blade.php`
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Laravel + Vue.js</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="bg-gray-50">
<div id="app"></div>
</body>
</html>
```
## Step 9: Setup Laravel Routes (SPA)
### `routes/web.php`
```php
<?php
use Illuminate\Support\Facades\Route;
// SPA Route - catch all and return main view
Route::get('/{any}', function () {
return view('welcome');
})->where('any', '.*');
```
## Step 10: Jalankan Development Server
```bash
# Terminal 1 - Laravel server
php artisan serve
# Terminal 2 - Vite dev server
npm run dev
```
Atau gunakan concurrently (jika sudah diinstall):
```bash
# Install concurrently jika belum
npm install --save-dev concurrently
# Tambahkan script di package.json
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "concurrently \"php artisan serve\" \"vite\""
}
# Jalankan keduanya sekaligus
npm run serve
```
## Struktur Project Final
```
project-name/
├── app/
├── resources/
│ ├── css/
│ │ └── app.css
│ ├── js/
│ │ ├── components/
│ │ │ └── App.vue
│ │ ├── pages/
│ │ │ ├── Home.vue
│ │ │ ├── About.vue
│ │ │ └── Contact.vue
│ │ ├── router/
│ │ │ └── index.js
│ │ └── app.js
│ └── views/
│ └── welcome.blade.php
├── routes/
│ └── web.php
├── package.json
├── vite.config.js
├── tailwind.config.js
└── composer.json
```
## Testing
Buka browser dan kunjungi:
- `http://localhost:8000` - Home page
- `http://localhost:8000/about` - About page
- `http://localhost:8000/contact` - Contact page
## Troubleshooting
### Error: "Component provided template option but runtime compilation is not supported"
- Pastikan `vue` alias sudah ditambahkan di `vite.config.js`
### Error: "Failed to parse source for import analysis"
- Pastikan `@vitejs/plugin-vue` sudah terinstall dan ditambahkan di plugins
### CSS tidak loading
- Pastikan `@vite` directive sudah benar di blade file
- Check jika Tailwind config sudah benar
### Router tidak bekerja
- Pastikan Laravel routes catch-all sudah ditambahkan
- Check browser console untuk error JavaScript
## Next Steps
- Tambahkan authentication
- Implementasikan API endpoints
- Setup state management (Pinia/Vuex)
- Tambahkan testing (Vitest)
- Deploy ke production
Selamat! Anda telah berhasil setup Laravel + Vue.js + Vue Router! 🎉