Uma aplicação moderna com Laravel como backend API e Vue.js 3
Backend: Laravel 12
Frontend: Vue.js 3 + Composition API
Roteamento: Vue Router 4
Gerenciamento de Estado: Pinia
HTTP Client: Axios
Build Tool: Vite
Styling: Tailwind CSS
laravel-vue-spa/
├── app/ # Backend Laravel
├── resources/
│ └── js/
│ ├── infra/ # Infraestrutura HTTP
│ ├── services/ # Serviços de domínio
│ ├── views/ # Componentes de página
│ ├── router/ # Configuração de rotas
│ ├── stores/ # Gerenciamento de estado
│ └── App.vue # Componente raiz
├── routes/
│ ├── api.php # Rotas da API
│ └── web.php # Rota SPA catch-all
└── resources/views/
└── app.blade.php # Template base
Components → Services → HTTP Clients → API Laravel
- Componente Vue chama serviço
- Service utiliza HTTP Client
- HTTP Client faz requisição para API Laravel
- Laravel processa e retorna dados
# Backend
composer install
cp .env.example .env
php artisan key:generate
# Frontend
npm install# Terminal 1 - Backend Laravel
php artisan serve
# Terminal 2 - Frontend Vue.js
npm run dev# Build do frontend
npm run build
# Servir aplicação
php artisan serve// resources/js/infra/http/HttpClient.js
const client = new HttpClient(baseURL)
await client.get('/endpoint')
await client.post('/endpoint', data)// resources/js/infra/http/ApiClient.js
import { apiGet, apiPost, ping } from '@/infra/http/ApiClient'
// Métodos HTTP
await apiGet('/users')
await apiPost('/users', data)
// Métodos específicos
await ping() // → GET /api/ping// resources/js/services/UserService.js
import { getUsers, createUser } from '@/services/UserService'
// Uso em componentes
const users = await getUsers()
const newUser = await createUser({ name: 'John' })// resources/js/services/ProductService.js
import { apiGet, apiPost } from '@/infra/http/ApiClient'
export const getProducts = () => apiGet('/products')
export const createProduct = (data) => apiPost('/products', data)<template>
<div>
<button @click="loadUsers">Carregar Usuários</button>
<div v-for="user in users" :key="user.id">
{{ user.name }}
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { getUsers } from '@/services/UserService'
const users = ref([])
const loadUsers = async () => {
users.value = await getUsers()
}
</script><script setup>
import { useUsers } from '@/services/UserService'
const { users, loading, fetchUsers } = useUsers()
// Busca automática ao montar componente
onMounted(fetchUsers)
</script>// resources/js/router/index.js
const routes = [
{ path: '/', component: Home },
]// routes/api.php
Route::get('/ping', fn() => response()->json(['status' => 'ok']));
Route::apiResource('/users', UserController::class);// routes/web.php
Route::get('/{any}', fn() => view('app'))->where('any', '.*');axios.defaults.baseURL = window.APP_URL + '/api'
axios.defaults.withCredentials = true
// CSRF token automático via interceptorexport default defineConfig({
plugins: [
laravel({ input: 'resources/js/app.js' }),
vue()
]
})