В этой статье мы создадим одностраничное приложение (SPA) на Vue.js с бэкендом на Laravel. Разберём:
✅ Настройку Laravel Sanctum для аутентификации
✅ Подключение Vue Router
✅ Пример CRUD (создание, чтение, обновление, удаление)
1. Настройка проекта
Установка Laravel и Vue
Создадим новый проект Laravel:
composer create-project laravel/laravel laravel-vue-spa
cd laravel-vue-spaУстановим Vue 3 и необходимые зависимости:
npm install vue@next vue-router @vitejs/plugin-vue axios
npm installНастройка Vite (vite.config.js)
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.js'],
refresh: true,
}),
vue(),
],
});Подготовка структуры Vue (resources/js/app.js)
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
createApp(App).use(router).mount('#app');2. Настройка Laravel Sanctum для аутентификации
Sanctum предоставляет простой способ аутентификации SPA.
Установка Sanctum
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrateКонфигурация CORS (config/cors.php)
Разрешим запросы с фронтенда:
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'],
'allowed_origins' => ['http://localhost:3000'], // URL вашего Vue-приложения
'supports_credentials' => true,Создание контроллера аутентификации
php artisan make:controller AuthControllerAuthController.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
public function login(Request $request) {
if (!Auth::attempt($request->only('email', 'password'))) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$request->session()->regenerate();
return response()->json(['user' => Auth::user()]);
}
public function logout(Request $request) {
Auth::logout();
$request->session()->invalidate();
return response()->json(['message' => 'Logged out']);
}Добавление маршрутов (routes/api.php)
use App\Http\Controllers\AuthController;
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum');3. Подключение Vue Router
Создадим файл маршрутизации для Vue.
Создание router.js
import { createRouter, createWebHistory } from 'vue-router';
import Login from './views/Login.vue';
import Dashboard from './views/Dashboard.vue';
const routes = [
{ path: '/login', component: Login },
{ path: '/dashboard', component: Dashboard, meta: { requiresAuth: true } },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
// Проверка аутентификации
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !localStorage.getItem('auth_token')) {
next('/login');
} else {
next();
}
});
export default router;4. Пример CRUD (управление задачами)
Создание модели и миграции
php artisan make:model Task -mМиграция (database/migrations/…_create_tasks_table.php)
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->boolean('completed')->default(false);
$table->timestamps();
});Запустим миграцию:
php artisan migrateСоздание API-контроллера
php artisan make:controller TaskController --apiTaskController.php
use App\Models\Task;
public function index() {
return Task::all();
}
public function store(Request $request) {
return Task::create($request->all());
}
public function update(Request $request, Task $task) {
$task->update($request->all());
return $task;
}
public function destroy(Task $task) {
$task->delete();
return response()->json(['message' => 'Task deleted']);
}Добавление маршрутов (routes/api.php)
use App\Http\Controllers\TaskController;
Route::apiResource('tasks', TaskController::class)->middleware('auth:sanctum');Vue-компонент для работы с задачами
resources/js/views/Dashboard.vue
<template>
<div>
<h1>Tasks</h1>
<ul>
<li v-for="task in tasks" :key="task.id">
{{ task.title }}
<button @click="deleteTask(task.id)">Delete</button>
</li>
</ul>
<input v-model="newTask.title" placeholder="Title">
<button @click="addTask">Add Task</button>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';
const tasks = ref([]);
const newTask = ref({ title: '', description: '' });
const fetchTasks = async () => {
const response = await axios.get('/api/tasks');
tasks.value = response.data;
};
const addTask = async () => {
await axios.post('/api/tasks', newTask.value);
fetchTasks();
};
const deleteTask = async (id) => {
await axios.delete(`/api/tasks/${id}`);
fetchTasks();
};
onMounted(fetchTasks);
</script>Итог
✔ Laravel Sanctum обеспечивает безопасную аутентификацию.
✔ Vue Router управляет навигацией в SPA.
✔ CRUD-операции позволяют удобно работать с данными.
Теперь у вас есть готовый каркас для SPA на Laravel + Vue! 🚀
Что дальше?


Добавить комментарий