Skip to content

rodrigodenner/laravel-vue-monolith

Repository files navigation

Laravel + Vue.js SPA

Uma aplicação moderna com Laravel como backend API e Vue.js 3


Tecnologias

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


Estrutura do Projeto

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

Arquitetura

Padrão de Camadas

Components → Services → HTTP Clients → API Laravel

Fluxo de Dados

  • Componente Vue chama serviço
  • Service utiliza HTTP Client
  • HTTP Client faz requisição para API Laravel
  • Laravel processa e retorna dados

Configuração

Instalação

# Backend
composer install
cp .env.example .env
php artisan key:generate

# Frontend
npm install

Desenvolvimento

# Terminal 1 - Backend Laravel
php artisan serve

# Terminal 2 - Frontend Vue.js
npm run dev

Produção

# Build do frontend
npm run build

# Servir aplicação
php artisan serve

API Clients

HttpClient (Camada Base)

// resources/js/infra/http/HttpClient.js
const client = new HttpClient(baseURL)
await client.get('/endpoint')
await client.post('/endpoint', data)

ApiClient (Configurado para /api)

// 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

Services

UserService Example

// resources/js/services/UserService.js
import { getUsers, createUser } from '@/services/UserService'

// Uso em componentes
const users = await getUsers()
const newUser = await createUser({ name: 'John' })

Criando um Novo Service

// resources/js/services/ProductService.js
import { apiGet, apiPost } from '@/infra/http/ApiClient'

export const getProducts = () => apiGet('/products')
export const createProduct = (data) => apiPost('/products', data)

Uso em Componentes

Exemplo Básico

<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>

Com Composables

<script setup>
import { useUsers } from '@/services/UserService'

const { users, loading, fetchUsers } = useUsers()

// Busca automática ao montar componente
onMounted(fetchUsers)
</script>

Rotas

Frontend (Vue Router)

// resources/js/router/index.js
const routes = [
  { path: '/', component: Home },
]

Backend (Laravel API)

// routes/api.php
Route::get('/ping', fn() => response()->json(['status' => 'ok']));
Route::apiResource('/users', UserController::class);

SPA Catch-all

// routes/web.php
Route::get('/{any}', fn() => view('app'))->where('any', '.*');

Configurações Importantes

Axios (resources/js/bootstrap.js)

axios.defaults.baseURL = window.APP_URL + '/api'
axios.defaults.withCredentials = true
// CSRF token automático via interceptor

Vite (vite.config.js)

export default defineConfig({
  plugins: [
    laravel({ input: 'resources/js/app.js' }),
    vue()
  ]
})

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages