Laravel создает панель администратора Vue с нуля — часть 4
Мы создали наш первый Vue CRUD в последних двух частях. Мы почти завершили CRUD разрешений, за исключением сортировки и авторизации столбцов. В этой части мы реализуем функциональность сортировки.
Следующие шаги необходимы для создания сортировки столбцов для нашей панели администрирования Laravel Vue.
- 1. Добавить заказПо
- 2. Создайте компонент сортировки
- 3. Включите компонент сортировки в компонент индекса.
1. Добавить заказПо
Мы собираемся добавить параметр строки запроса sort
в URL-адрес. Основываясь на приведенном ниже значении сортировки, мы делаем порядок.
sort=name для порядка ASC
sort=-name для заказа DESC
Откройте функцию индекса в контроллере разрешений и добавьте функцию замены индекса с помощью приведенного ниже кода.
app/Http/Controllers/Admin/PermissionController.php
public function index() { $permissions = (new Permission)->newQuery(); if (request()->has('search')) { $permissions->where('name', 'Like', '%'.request()->input('search').'%'); } if (request()->query('sort')) { $attribute = request()->query('sort'); $sort_order = 'ASC'; if (strncmp($attribute, '-', 1) === 0) { $sort_order = 'DESC'; $attribute = substr($attribute, 1); } $permissions->orderBy($attribute, $sort_order); } else { $permissions->latest(); } $permissions = $permissions->paginate(5)->onEachSide(2)->appends(request()->query()); return Inertia::render('Admin/Permission/Index', [ 'permissions' => $permissions, 'filters' => request()->all('search'), ]); }
Не забудьте добавить request()->query()
к ссылкам на страницы.
$permissions->paginate(5)->onEachSide(2)->appends(request()->query());
Теперь перейдите на страницу разрешений в браузере с sort=name
параметром запроса. Он показывает результаты заказа ASC. Также проверьте порядок DESC с помощью sort=-name
.
2. Создайте компонент сортировки
Создайте новый компонент сортировки для отображения имени столбца со ссылками сортировки и значками сортировки. Скопируйте приведенный ниже код и создайте компонент сортировки в папке Component/Admin.
resources/js/Components/Admin/Sort.vue
<script setup> import { ref, computed } from "vue"; import { Link } from "@inertiajs/inertia-vue3"; const props = defineProps({ label: { type: String, default: "", }, attribute: { type: String, default: "", }, }); const downFill = ref("lightgray"); const upFill = ref("lightgray"); const sortLink = computed(() => { let url = new URL(document.location); let sortValue = url.searchParams.get("sort"); if (sortValue == props.attribute) { url.searchParams.set("sort", "-" + props.attribute); upFill.value = "black"; } else if (sortValue === "-" + props.attribute) { url.searchParams.set("sort", props.attribute); downFill.value = "black"; } else { url.searchParams.set("sort", props.attribute); } return url.href; }); </script> <template> <div class="flex items-center gap-4"> <Link :href="sortLink" class="no-underline hover:underline text-cyan-600 dark:text-cyan-400" >{{ label }}</Link > <div class="flex flex-col"> <svg class="inline-block" xmlns="http://www.w3.org/2000/svg" width="15px" height="15px" viewBox="0 0 15 15" fill="none" > <path d="M7.5 3L15 11H0L7.5 3Z" :fill="upFill" /> </svg> <svg class="inline-block" xmlns="http://www.w3.org/2000/svg" width="15px" height="15px" viewBox="0 0 15 15" fill="none" > <path d="M7.49988 12L-0.00012207 4L14.9999 4L7.49988 12Z" :fill="downFill" /> </svg> </div> </div> </template>
Компонент сортировки имеет свойства метки и атрибута. Кроме того, в компоненте мы использовали реактивную ref() Vue для заливки цветом для сортировки значка SVG.
3. Включите компонент сортировки в компонент индекса.
на последнем шаге мы импортируем компонент сортировки в Index.vue
и включим компонент сортировки в столбец заголовка таблицы.
<Sort label="Name" attribute="name" />
Откройте компонент Index.vue
и замените приведенным ниже кодом.
resources/js/Pages/Admin/Permission/Index.vue
<script setup> import BreezeAuthenticatedLayout from "@/Layouts/Authenticated.vue"; import { Head, Link, useForm } from "@inertiajs/inertia-vue3"; import BreezeButton from "@/Components/Button.vue"; import Pagination from "@/Components/Admin/Pagination.vue"; import Sort from "@/Components/Admin/Sort.vue"; const props = defineProps({ permissions: { type: Object, default: () => ({}), }, filters: { type: Object, default: () => ({}), }, }); const form = useForm({ search: props.filters.search, }); const formDelete = useForm({}); function destroy(id) { if (confirm("Are you sure you want to delete?")) { formDelete.delete(route("permission.destroy", id)); } } </script> <template> <Head title="Permissions" /> <BreezeAuthenticatedLayout> <template #header> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> Permissions </h2> </template> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div v-if="$page.props.flash.message" class=" p-4 mb-4 text-sm text-green-700 bg-green-100 rounded-lg dark:bg-green-200 dark:text-green-800 " role="alert" > <span class="font-medium"> {{ $page.props.flash.message }} </span> </div> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div class="p-6 bg-white border-b border-gray-200"> <div class="flex flex-col mt-8"> <div class="d-print-none with-border mb-8"> <Link :href="route('permission.create')" class=" text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 " >Add Permission</Link > </div> <div class="py-2"> <div class=" min-w-full border-b border-gray-200 shadow overflow-x-auto " > <form @submit.prevent="form.get(route('permission.index'))"> <div class="py-2 flex"> <div class="flex pl-4"> <input type="search" v-model="form.search" class=" rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 " placeholder="Search" /> <button type="submit" class=" ml-4 inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:ring ring-gray-300 disabled:opacity-25 transition ease-in-out duration-150 " > Search </button> </div> </div> </form> <table class="border-collapse table-auto w-full text-sm"> <thead> <tr> <th class=" py-2 px-4 bg-gray-50 font-bold uppercase text-sm text-grey-dark border-b border-grey-light text-left " > <Sort label="Name" attribute="name" /> </th> <th class=" py-2 px-4 bg-gray-50 font-bold uppercase text-sm text-grey-dark border-b border-grey-light text-left " > Actions </th> </tr> </thead> <tbody class="bg-white dark:bg-slate-800"> <tr v-for="permission in permissions.data" :key="permission.id" > <td class=" border-b border-slate-100 dark:border-slate-700 p-4 pl-8 text-slate-500 dark:text-slate-400 " > <div class="text-sm text-gray-900"> <Link :href="route('permission.show', permission.id)" class=" no-underline hover:underline text-cyan-600 dark:text-cyan-400 " >{{ permission.name }}</Link > </div> </td> <td class=" border-b border-slate-100 dark:border-slate-700 p-4 pl-8 text-slate-500 dark:text-slate-400 " > <div class="flex"> <Link :href="route('permission.edit', permission.id)" class=" inline-flex items-center px-4 py-2 text-white mr-4 bg-blue-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray transition ease-in-out duration-150 px-4 py-2 text-white " > Edit </Link> <BreezeButton class="px-4 py-2 text-white bg-red-600" @click="destroy(permission.id)" > Delete </BreezeButton> </div> </td> </tr> </tbody> </table> </div> <div class="py-8"> <Pagination class="mt-6" :data="permissions" /> </div> </div> </div> </div> </div> </div> </div> </BreezeAuthenticatedLayout> </template>
Репозиторий GitHub
Панель администратора Laravel Vue доступна на https://github.com/balajidharma/laravel-vue-admin-panel. Установите панель администратора и поделитесь своим мнением.
Спасибо за чтение.
Оставайтесь с нами, чтобы узнать больше!
Подпишитесь на меня balajidharma.medium.com.
Предыдущая часть — Часть 3: Создание Laravel CRUD, создание и обновление страниц с использованием Inertia и Vue
Следующая часть — Часть 5: Авторизация Laravel CRUD с помощью Inertia и Vue — Контроль доступа с использованием роли и разрешения