Автор: Андрей Ковалёв
Разработчик и технический редактор SkilledBird. Несколько лет строил full-stack проекты на PHP, Laravel и Vue.js, сейчас фокусируюсь на архитектуре и поддержке реальных приложений.

Если ты собираешь портфолио и хочешь показать не только умение «сверстать форму», а понимание того, как устроено приложение целиком, CRUD-приложение на Laravel и Vue.js — один из самых практичных форматов. Это уже не учебный фрагмент, а законченный мини-продукт: есть backend API, frontend-интерфейс, база данных, базовая безопасность и понятная структура проекта. За 1–2 дня реально собрать демо, которое будет выглядеть не как случайный pet-проект, а как аккуратная инженерная работа.

Ценность такого проекта в том, что он показывает сразу несколько слоёв разработки: маршруты и контроллеры на backend, модели и миграции, компоненты Vue, работу с API, обработку форм, валидацию, базовую организацию кода. В статье разберём, как собрать CRUD-приложение на Laravel и Vue.js шаг за шагом — от подготовки окружения до деплоя. При этом я буду делать акцент не только на том, что нужно сделать, но и почему это считается нормальной практикой в реальной разработке.

Зачем Laravel и Vue.js для портфолио-CRUD?

Laravel хорошо подходит для такого проекта, потому что забирает на себя большое количество рутинной инфраструктуры: миграции, Eloquent ORM, валидацию, маршрутизацию, аутентификацию и работу с API. Vue.js, в свою очередь, даёт реактивный интерфейс без лишней сложности и позволяет быстро собрать SPA, которая выглядит современно и при этом остаётся понятной в поддержке. В связке это действительно классический стек для небольшого full-stack-приложения с API.

Для портфолио это удачный выбор по нескольким причинам:

  • Ты демонстрируешь полный цикл разработки: backend на REST API, frontend на Vue 3 Composition API, работу с MySQL или PostgreSQL.
  • Такой проект легко развивать без переписывания с нуля: можно добавить аутентификацию, пагинацию, фильтры, тесты, CI/CD и получить уже вполне взрослую структуру.
  • Работодатели действительно ищут практические репозитории по запросам вроде «CRUD на Laravel Vue.js», и аккуратно оформленный проект в GitHub здесь работает лучше, чем десяток разрозненных сниппетов.

Хороший пример сущности — каталог книг. В нём естественно раскрываются все четыре CRUD-операции: Create — добавить книгу, Read — показать список и детали, Update — отредактировать запись, Delete — удалить. Ровно та же схема потом масштабируется на блог, каталог товаров, простую CRM-админку или внутренний интерфейс для контент-менеджмента.

С инженерной точки зрения это ещё и удобный формат, чтобы показать, что ты умеешь разделять ответственность между слоями приложения. Даже простой CRUD можно сделать либо как хаотичный набор файлов, либо как поддерживаемый проект, где есть понятные ресурсы, предсказуемые API-ответы, валидация и нормальная организация компонентов. Для портфолио важен именно второй вариант.

Подготовка окружения: 5 минут на запуск

На старте лучше не усложнять себе жизнь экзотическими настройками. Твоя задача — быстро поднять рабочее окружение и как можно раньше перейти к коду и архитектуре. Для этого установи:

  1. PHP 8.2+, Composer, Node.js 18+.
  2. Базу данных: Laravel Sail (Docker) или локальный MySQL.
  3. IDE: VS Code с Laravel и Vite extensions.

После установки обязательно проверь версии: php artisan --version и npm --version. Это банальная мелочь, но именно на несовместимых версиях чаще всего теряется время в начале проекта. Если всё в порядке — сразу инициализируй репозиторий: git init && git add . && git commit -m "Init Laravel + Vue CRUD".

На практике это важнее, чем кажется. Когда проект даже совсем маленький, ранняя фиксация базового состояния в Git помогает безопасно экспериментировать: подключать Vue, перестраивать API, добавлять Sanctum, не боясь сломать рабочую точку входа. Это уже элемент нормальной инженерной дисциплины, а не формальность «для галочки».

Таблица зависимостей для CRUD на Laravel Vue.js

Компонент Пакет Команда установки Зачем?
Backend API Laravel Sanctum php artisan install:api Токены для SPA
Frontend Vue 3 + Vite Уже в Laravel (Breeze) Быстрый рендер
UI Tailwind CSS npm install -D tailwindcss Стили без боли
HTTP Axios npm install axios Запросы к API

Если говорить о практическом выборе, то этот набор вполне разумен для портфолио. Он не перегружает проект, но закрывает всё необходимое. Единственный комментарий: не стоит тащить дополнительные библиотеки только ради «богатого стека». На собеседовании куда лучше выглядит небольшой, но чисто организованный проект, чем нагромождение зависимостей, из которых половина не используется.

Backend: Laravel API для CRUD операций

Теперь переходим к серверной части. Laravel CRUD в адекватной реализации — это не просто контроллер с пятью методами, а связка из моделей, миграций, ресурсов, валидации и маршрутов. Даже в маленьком приложении полезно сразу придерживаться REST-подхода: это делает код предсказуемым, а API — удобным для тестирования и расширения.

Шаг 1: Модель и миграция

database/migrations/xxx_create_books_table.php:

После создания миграции запусти php artisan migrate. Затем быстро проверь модель через Tinker: php artisan tinkerBook::create(['title' => 'Test']);Book::all();.

Такой smoke-test полезен сразу после настройки модели и таблицы. Он помогает рано поймать типичные проблемы: забытые fillable-поля, неверные типы колонок, проблемы с подключением к БД. На реальных проектах ранняя проверка экономит много времени, особенно если позже поверх этой модели начнут работать API-ресурсы, фильтрация и формы на фронтенде.

Если хочешь, чтобы код выглядел профессиональнее, не ограничивайся только минимальным набором полей. Даже в учебном CRUD имеет смысл подумать о структуре данных: где нужны индексы, какие поля обязательны, где могут понадобиться ограничения по длине, нужен ли nullable(). Поддерживаемость базы начинается именно с миграций, а не тогда, когда приложение уже в проде и схему приходится править на живых данных.

Шаг 2: Контроллер и ресурсы

app/Http/Controllers/BookController.php (методы index, store, show, update, destroy):

app/Http/Resources/BookResource.php:

Маршруты routes/api.php:

После этого проверь API локально: php artisan serve, затем открой Postman и протестируй http://localhost:8000/api/books. Прогони GET/POST/PUT/DELETE и убедись, что ответы предсказуемые, а не «что получилось». Если всё работает — backend действительно готов для интеграции с Vue.

Почему это важно? В реальных проектах API — это основа взаимодействия между сервисами, клиентами и внутренними интерфейсами. Даже если у тебя один frontend и один backend в одном репозитории, подход к API должен быть таким же, как в нормальной production-разработке: явные контракты, единый формат ответа, валидация входных данных, отсутствие лишней бизнес-логики в контроллере.

Отдельно отмечу качество кода. Для портфолио лучше сразу выносить форматирование ответа в Resource, а правила валидации — хотя бы в контроллер, а ещё лучше в Form Request. Это делает проект заметно чище. Когда ревьюер видит, что у тебя контроллер не раздувается до 200 строк, а данные не сериализуются хаотично, это считывается как понимание поддерживаемой архитектуры, а не просто умение «заставить работать».

Frontend: Vue.js SPA с CRUD на Laravel

На клиентской стороне задача простая: собрать понятный SPA-интерфейс, который общается с Laravel API. Для портфолио я бы действительно не усложнял проект Inertia.js, если цель — показать классическую работу с API. Чистый Vite + Axios в данном случае проще, прозрачнее и лучше демонстрирует понимание границы между frontend и backend.

Шаг 1: Настрой Vite и компоненты

vite.config.js:

resources/js/app.js:

На этом этапе важно не только «подключить Vue», но и сразу договориться с собой о структуре файлов. Даже если компонентов пока два-три, лучше заранее разложить их по понятным директориям: отдельно базовые UI-компоненты, отдельно feature-компоненты, отдельно сервисы для API-запросов. Такой подход потом облегчает рефакторинг и избавляет от ситуации, когда через неделю весь frontend живёт в одном BooksList.vue.

Шаг 2: Главный компонент BooksList.vue

resources/js/components/BooksList.vue (Composition API):

Добавь модалки для Create/Update. Если хочешь сделать проект визуально и архитектурно сильнее, можно подключить Pinia для управления состоянием, но только если это действительно упрощает код, а не добавляет лишний слой ради строчки в README.

resources/views/welcome.blade.php:

Собери фронтенд через npm run dev. Затем открой / и проверь, что список книг подтягивается из API. Следующий шаг — формы: поля ввода и запрос axios.post('/api/books', data) для создания записи, затем обновление списка без перезагрузки страницы.

Проверка: открой DevTools → Network и посмотри, как идут запросы. Если видишь корректные обращения к API и предсказуемые ответы, значит связка Laravel + Vue действительно работает как единое приложение.

С точки зрения качества реализации тут есть несколько практических замечаний. Во-первых, не складывай всю логику загрузки, создания, редактирования и удаления в один огромный компонент без разделения ответственности. Даже в учебном проекте лучше вынести API-вызовы в отдельный модуль, а формы — в переиспользуемый компонент. Во-вторых, Composition API действительно удобен, когда логика начинает расти: в нём проще организовать реактивные состояния, хуки загрузки и обработчики формы так, чтобы код оставался читаемым.

Если хочешь, чтобы проект выглядел как работа разработчика, а не как результат видеоурока, добавь базовую обработку ошибок и состояний интерфейса: loading, empty state, validation error, disabled-кнопки на время запроса. Это мелочи, но именно они показывают понимание пользовательского потока и того, как ведёт себя приложение в неидеальных условиях.

Интеграция: Axios + CSRF для безопасности

Когда frontend и backend начинают работать вместе, важно не забыть про безопасность запросов. Laravel ожидает корректную CSRF-защиту для POST/PUT/DELETE-операций, и если этот слой пропустить, приложение может вести себя нестабильно уже на первых тестах.

resources/js/bootstrap.js:

В .env укажи: SESSION_DRIVER=cookie, SANCTUM_STATEFUL_DOMAINS=localhost.

После этого Vue.js CRUD с Laravel работает как единый монолит с привычной браузерной сессией. Для демо этого более чем достаточно. Деплой можно сделать на Heroku или аналогичную платформу командой git push heroku main.

На практике здесь важно понимать, что безопасность — это не «дополнительная опция», а часть архитектуры. Даже если проект маленький, наличие корректной CSRF-настройки, осмысленной работы с сессиями и предсказуемого поведения API при неавторизованных запросах показывает зрелый подход. Работодатель обычно быстро замечает разницу между проектом, где безопасность просто упомянута, и проектом, где она реально учтена в интеграции клиента и сервера.

Чек-лист готового CRUD-приложения на Laravel Vue.js

  • Миграции + сеялеры (php artisan make:seeder BookSeeder)
  • Пагинация в API (paginate(15))
  • Формы с валидацией (Laravel + VeeValidate в Vue)
  • Tailwind для responsive
  • README.md с скринами, стеком, инструкцией по запуску

Этот чек-лист стоит воспринимать не как формальный набор галочек, а как минимальные признаки законченного проекта. Например, сидеры делают приложение воспроизводимым: любой, кто клонирует репозиторий, сможет быстро поднять демонстрационные данные. Пагинация показывает, что ты думаешь о масштабировании списка. README — вообще недооценённая часть портфолио: часто именно по нему делают первый вывод о том, насколько разработчик умеет оформлять и передавать проект дальше по команде.

Расширения: от демо к реальному продукту

Когда базовый CRUD уже работает, у тебя появляется хорошая основа для развития. И это как раз тот момент, где можно показать не только владение фреймворком, но и инженерное мышление.

Для портфолио+ добавь:

  • Аутентификация: php artisan breeze:install api + Vue login.
  • Тесты: php artisan make:test BookTest (Pest/PHPUnit) + Vitest для Vue.
  • PWA: Vite PWA plugin.
  • Docker: Dockerfile + docker-compose.yml.

Ситуации применения:

  • Junior: Базовый CRUD — уже достаточно для собеседования, если проект аккуратно оформлен и стабильно запускается.
  • Middle: Добавь поиск и фильтры через Query Builder в Laravel, а также нормальную организацию API-параметров.
  • Команда: Подключи GitHub Actions для CI/CD.

Проблемы и фиксы:

  • CORS? php artisan config:cache.
  • 404 на API? Проверь api prefix в routes.
  • Медленно? Добавь индексы в миграции.

Если смотреть на это как на реальную эволюцию проекта, то следующий качественный шаг после CRUD — тестируемость и автоматизация. Тесты на Laravel позволяют зафиксировать поведение API и не ломать базовые сценарии при рефакторинге. Тесты на Vue помогают не бояться изменений в формах и списках. CI/CD через GitHub Actions — это уже сигнал, что ты понимаешь не только локальную разработку, но и процесс поставки изменений.

Отдельно про Docker: для портфолио он полезен не потому, что «так модно», а потому что делает проект воспроизводимым. Когда ревьюеру или работодателю не нужно вручную настраивать окружение, шанс, что твой проект действительно запустят и посмотрят, становится выше. То же касается сидеров, health-check’ов и чёткой инструкции запуска.

И ещё один момент из практики: не пытайся добавить в демо всё сразу. Лучше один хорошо реализованный сценарий — например, книги с поиском, пагинацией, валидацией, тестами и деплоем, — чем набор полуготовых фич. Поддерживаемость оценивается не по числу технологий, а по качеству реализации и связности архитектуры.

FAQ: вопросы по сборке CRUD на Laravel и Vue.js

Сколько времени уйдёт на CRUD-приложение Laravel Vue.js?

Обычно 1–3 дня. Backend реально собрать за 2 часа, frontend — примерно за 4 часа, остальное уйдёт на полировку: валидацию, оформление UI, README, сидеры, деплой и проверку сценариев. Если делать проект не «на скорую руку», а в портфолио, именно финальная доводка и занимает заметную часть времени.

Можно ли без Vue.js, чистый Blade?

Да, можно. Но для портфолио SPA обычно смотрится сильнее, потому что Vue показывает современный подход к frontend-части: реактивность, работу с API, компонентную архитектуру. Blade хорош для серверного рендера, но если задача — показать full-stack в актуальном виде, Vue здесь даёт более наглядный результат.

Как добавить поиск в Laravel CRUD?

На backend это можно сделать прямо в контроллере: Book::where('title', 'like', "%{$query}%")->get();. На frontend — повесить debounce на input, чтобы не отправлять запрос на каждую букву мгновенно. В реальном приложении я бы ещё подумал о нормализации параметров запроса, пагинации результатов поиска и индексации полей, если данных станет больше.

Деплой Laravel Vue.js CRUD на бесплатный хостинг?

Подойдут Render.com или Railway: пушишь код в Git, дальше платформа собирает проект автоматически. Для портфолио это удобный вариант, потому что можно быстро показать live-демо без сложной ручной инфраструктуры. Главное — не забыть проверить переменные окружения, подключение к базе и сборку фронтенда на удалённой стороне.

Что если база SQLite вместо MySQL?

Тогда в .env укажи DB_CONNECTION=sqlite. Для локальной разработки и быстрых демо это нормальный вариант: миграции запускаются быстро, а стартовый порог настройки ниже. Но если хочешь приблизить проект к production-реальности, MySQL или PostgreSQL всё же лучше, потому что они чаще встречаются в боевых сценариях и дают более реалистичную среду для тестирования запросов и индексов.

Когда проект собран, не останавливайся на локальном запуске. Загрузи его на GitHub, добавь live-демо — например, frontend можно разместить на Netlify, а backend на Railway. Для портфолио это действительно имеет значение: живой проект воспринимается намного серьёзнее, чем просто архив со скриншотами. Если всё оформить аккуратно — с понятным README, скриншотами, стеком, инструкцией запуска и ссылкой на деплой, — такой CRUD уже становится хорошим аргументом в пользу твоего full-stack профиля.

Итог простой: CRUD-приложение на Laravel и Vue.js — это не «слишком базово», если оно сделано качественно. Наоборот, это хороший формат, чтобы показать зрелость в мелочах: структуру проекта, чистоту API, валидацию, предсказуемость UI, тестируемость и способность довести решение до рабочего состояния. Именно это обычно и отличает учебный код от инженерной практики.