Июль 24, 2022, Originally published at laraveltuts.com・9 min read
Сегодня мы собираемся изучить Laravel 9 Vue JS CRUD приложение с использованием примера Vite. В этом уроке мы рассмотрим приложение Laravel 9 Vue Js CRUD с использованием Vite в последнем обновлении Laravel с примером.
Vite — это современный инструмент сборки фронтенда, который обеспечивает чрезвычайно быструю среду разработки и собирает ваш код для производства. При создании приложений на Laravel вы обычно используете Vite для компоновки CSS и JavaScript файлов вашего приложения в готовые для производства активы.
Vue.js — это фронт-энд JavaScript-фреймворк с открытым исходным кодом модели-вида-вида для создания пользовательских интерфейсов и одностраничных приложений. Он был создан Эваном Ю, и поддерживается им и остальными активными членами основной команды.
- Шаги для Laravel 9 Vue JS CRUD App на примере Vite:
- Шаг 1: Установка нового свежего приложения Laravel 9
- Шаг 2: Создание базы данных и конфигурации
- Шаг 3: Создание авторизации с помощью Breeze
- Шаг 4: Создание миграции и модели
- Шаг 5: Создание маршрута
- Шаг 6: Создание контроллера
- Шаг 7: Создание страниц Vue
- Шаг 8: Тестирование
- Шаг 9: Заключение
Шаги для Laravel 9 Vue JS CRUD App на примере Vite:
- Шаг 1: Установка нового приложения Laravel 9
- Шаг 2: Создание базы данных и конфигурации
- Шаг 3: Создание авторизации с помощью Breeze
- Шаг 4: Создание миграции и модели
- Шаг 5: Создание маршрута
- Шаг 6: Создание контроллера
- Шаг 7: Создание страниц Vue
- Шаг 8: Тестирование
- Шаг 9: Заключение
Шаг 1: Установка нового свежего приложения Laravel 9
Сначала мы установим новое приложение laravel 9. Чтобы установить приложение laravel, выполните следующую команду в терминале.
composer create-project laravel/laravel vuejs-crud-vite
cd vuejs-crud-vite
Примечание: «vuejs-crud-vite» — это название нашего приложения laravel.
Шаг 2: Создание базы данных и конфигурации
Теперь мы создадим базу данных. Сначала откройте phpmyadmin и создайте базу данных с именем «vuejs-crud-vite» (вы можете использовать любое имя).
Теперь мы собираемся добавить данные базы данных в приложение laravel. Откройте файл .env и введите данные базы данных.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=vuejs-crud-vite
DB_USERNAME=root
DB_PASSWORD=
Шаг 3: Создание авторизации с помощью Breeze
Теперь мы собираемся создать аутентификацию с помощью Breeze. Выполните следующую команду в терминале, чтобы установить библиотеку breeze.
composer require laravel/breeze --dev
Создайте аутентификацию с помощью следующей команды.
php artisan breeze:install vue
Установите пакет Node JS.
npm install
Теперь запустите команду vite и заставьте ее продолжать работать.
npm run dev
Примечание: Если возникла ошибка, обновите узел до версии 16.16.0, и он заработал.
Теперь откройте новый терминал и запустите миграцию.
php artisan migrate
Шаг 4: Создание миграции и модели
Здесь мы собираемся создать миграцию для таблицы Posts. Для создания миграции Posts выполните следующую команду.
php artisan make:migration create_posts_table
добавьте следующие поля в файл миграции posts.
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
Запустите миграцию еще раз, чтобы создать таблицу posts.
php artisan migrate
Теперь мы создадим модель Post. Для создания модели Post выполните следующую команду в терминале.
php artisan make:model Post
И добавьте следующий код в модель Post.php.
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Post extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'title', 'body'
];
}
Шаг 5: Создание маршрута
Теперь мы создадим маршрут ресурсов для нашего CRUD-приложения. Добавьте следующий маршрут в routes/web.php
<?php
use IlluminateFoundationApplication;
use IlluminateSupportFacadesRoute;
use InertiaInertia;
use AppHttpControllersPostController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return Inertia::render('Welcome', [
'canLogin' => Route::has('login'),
'canRegister' => Route::has('register'),
'laravelVersion' => Application::VERSION,
'phpVersion' => PHP_VERSION,
]);
});
Route::get('/dashboard', function () {
return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
require __DIR__.'/auth.php';
Route::resource('posts', PostController::class);
Шаг 6: Создание контроллера
В этом шаге мы создадим контроллер Post Controller. Создайте новый файл PostController.php в папке app/Http/Controllers и добавьте в него следующий код.
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use InertiaInertia;
use AppModelsPost;
use IlluminateSupportFacadesValidator;
class PostController extends Controller
{
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function index()
{
$posts = Post::all();
return Inertia::render('Posts/Index', ['posts' => $posts]);
}
/**
* Write code on Method
*
* @return response()
*/
public function create()
{
return Inertia::render('Posts/Create');
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function store(Request $request)
{
Validator::make($request->all(), [
'title' => ['required'],
'body' => ['required'],
])->validate();
Post::create($request->all());
return redirect()->route('posts.index');
}
/**
* Write code on Method
*
* @return response()
*/
public function edit(Post $post)
{
return Inertia::render('Posts/Edit', [
'post' => $post
]);
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function update($id, Request $request)
{
Validator::make($request->all(), [
'title' => ['required'],
'body' => ['required'],
])->validate();
Post::find($id)->update($request->all());
return redirect()->route('posts.index');
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function destroy($id)
{
Post::find($id)->delete();
return redirect()->route('posts.index');
}
}
Шаг 7: Создание страниц Vue
На этом последнем шаге мы создадим страницы Vue Js — Index.vue, Create.vue и Edit.vue.
Создайте новую папку Posts в папке resources/js/Pages и создайте следующие страницы в папке Posts.
resources/js/Pages/Posts/Index.vue
<script setup>
import BreezeAuthenticatedLayout from '@/Layouts/Authenticated.vue';
import { Head, Link, useForm } from '@inertiajs/inertia-vue3';
defineProps({
posts: Array,
});
const form = useForm();
function destroy(id) {
if (confirm("Are you sure you want to Delete")) {
form.delete(route('posts.destroy', id));
}
}
</script>
<template>
<Head title="Dashboard" />
<BreezeAuthenticatedLayout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Laravel 9 Vue JS CRUD App using Vite Example - LaravelTuts.com
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<div className="flex items-center justify-between mb-6">
<Link
className="px-6 py-2 text-white bg-green-500 rounded-md focus:outline-none"
:href="route('posts.create')"
>
Create Post
</Link>
</div>
<table className="table-fixed w-full">
<thead>
<tr className="bg-gray-100">
<th className="px-4 py-2 w-20">No.</th>
<th className="px-4 py-2">Title</th>
<th className="px-4 py-2">Body</th>
<th className="px-4 py-2">Action</th>
</tr>
</thead>
<tbody>
<tr v-for="post in posts">
<td className="border px-4 py-2">{{ post.id }}</td>
<td className="border px-4 py-2">{{ post.title }}</td>
<td className="border px-4 py-2">{{ post.body }}</td>
<td className="border px-4 py-2">
<Link
tabIndex="1"
className="px-4 py-2 text-sm text-white bg-blue-500 rounded"
:href="route('posts.edit', post.id)"
>
Edit
</Link>
<button
@click="destroy(post.id)"
tabIndex="-1"
type="button"
className="mx-1 px-4 py-2 text-sm text-white bg-red-500 rounded"
>
Delete
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</BreezeAuthenticatedLayout>
</template>
resources/js/Pages/Posts/Create.vue
<script setup>
import BreezeAuthenticatedLayout from '@/Layouts/Authenticated.vue';
import BreezeLabel from '@/Components/Label.vue';
import BreezeInput from '@/Components/Input.vue';
import BreezeTextArea from '@/Components/Textarea.vue';
import { Head, Link, useForm } from '@inertiajs/inertia-vue3';
const form = useForm({
title: '',
body: ''
});
const submit = () => {
form.post(route('posts.store'));
};
</script>
<template>
<Head title="Dashboard" />
<BreezeAuthenticatedLayout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Create Post
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<div className="flex items-center justify-between mb-6">
<Link
className="px-6 py-2 text-white bg-blue-500 rounded-md focus:outline-none"
:href="route('posts.index')"
>
Back
</Link>
</div>
<form name="createForm" @submit.prevent="submit">
<div className="flex flex-col">
<div className="mb-4">
<BreezeLabel for="title" value="Title" />
<BreezeInput
id="title"
type="text"
class="mt-1 block w-full"
v-model="form.title"
autofocus />
<span className="text-red-600" v-if="form.errors.title">
{{ form.errors.title }}
</span>
</div>
<div className="mb-4">
<BreezeLabel for="body" value="Body" />
<BreezeTextArea
id="body"
class="mt-1 block w-full"
v-model="form.body"
autofocus />
<span className="text-red-600" v-if="form.errors.body">
{{ form.errors.body }}
</span>
</div>
</div>
<div className="mt-4">
<button
type="submit"
className="px-6 py-2 font-bold text-white bg-green-500 rounded"
>
Save
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</BreezeAuthenticatedLayout>
</template>
ресурсы/js/Pages/Posts/Edit.vue
<script setup>
import BreezeAuthenticatedLayout from '@/Layouts/Authenticated.vue';
import BreezeLabel from '@/Components/Label.vue';
import BreezeInput from '@/Components/Input.vue';
import BreezeTextArea from '@/Components/Textarea.vue';
import { Head, Link, useForm } from '@inertiajs/inertia-vue3';
const props = defineProps({
post: Object,
});
const form = useForm({
title: props.post.title,
body: props.post.body
});
const submit = () => {
form.put(route('posts.update', props.post.id));
};
</script>
<template>
<Head title="Dashboard" />
<BreezeAuthenticatedLayout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Edit Post
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<div className="flex items-center justify-between mb-6">
<Link
className="px-6 py-2 text-white bg-blue-500 rounded-md focus:outline-none"
:href="route('posts.index')"
>
Back
</Link>
</div>
<form name="createForm" @submit.prevent="submit">
<div className="flex flex-col">
<div className="mb-4">
<BreezeLabel for="title" value="Title" />
<BreezeInput
id="title"
type="text"
class="mt-1 block w-full"
v-model="form.title"
autofocus />
<span className="text-red-600" v-if="form.errors.title">
{{ form.errors.title }}
</span>
</div>
<div className="mb-4">
<BreezeLabel for="body" value="Body" />
<BreezeTextArea
id="body"
class="mt-1 block w-full"
v-model="form.body"
autofocus />
<span className="text-red-600" v-if="form.errors.body">
{{ form.errors.body }}
</span>
</div>
</div>
<div className="mt-4">
<button
type="submit"
className="px-6 py-2 font-bold text-white bg-green-500 rounded"
>
Save
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</BreezeAuthenticatedLayout>
</template>
Создайте новый файл Textaarea.vue внутри ресурсов/js/Components
resources/js/Components/Textarea.vue
<script setup>
import { onMounted, ref } from 'vue';
defineProps(['modelValue']);
defineEmits(['update:modelValue']);
const input = ref(null);
onMounted(() => {
if (input.value.hasAttribute('autofocus')) {
input.value.focus();
}
});
</script>
<template>
<textarea class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" ref="input"></textarea>
</template>
Добавьте Post Navigation в файле Authenticated.vue внутри папки resources/js/Layouts.
<!-- Navigation Links -->
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
<BreezeNavLink :href="route('dashboard')" :active="route().current('dashboard')">Dashboard</BreezeNavLink>
<BreezeNavLink :href="route('posts.index')" :active="route().current('posts.index')">Posts</BreezeNavLink>
</div>
Шаг 8: Тестирование
Теперь давайте протестируем наше приложение Laravel 9 Vue JS CRUD на примере Vite. Выполните следующую команду для запуска сервера laravel.
php artisan serve
Также запустите Vite в новом терминале и запустите его.
npm run dev
или сборку.
npm run build
Теперь откройте любой веб-браузер и введите следующую ссылку для тестирования приложения.
http://127.0.0.1:8000/
Примечание: Зарегистрируйте нового пользователя, а затем щелкните посты в навигации.
Предварительный просмотр:
Шаг 9: Заключение
Сегодня мы изучили Laravel 9 Vue JS CRUD App на примере Vite. Надеюсь, этот учебник помог вам в изучении Laravel 9. Если у вас есть вопросы, вы можете задать их нам в разделе комментариев ниже. Если вам понравился этот урок, пожалуйста, подпишитесь на наш канал YouTube и следите за нами в социальных сетях Facebook и Instagram.