我在我的Laravel Nova自定义工具中使用Laravel-vue-pagination和renderless pagination(laravel-vue-pagination.org)。我的分页工作在标准的每页10个项目,但我希望能够改变itemsPerPage下拉列表,并有这个设置每页的项目数。
下面是我的管理器组件代码:
<div>
<Heading :level="1" class="mb-3 flex items-center">
<span>Adverts</span>
</Heading>
<div class="flex mb-6">
<IndexSearchInput
:placeholder="searchPlaceholder"
/>
<div class="w-full flex items-center" >
<!-- Create / Attach Button -->
</div>
</div>
<Card>
<div class="flex flex-col md:flex-row md:items-center py-3 border-b border-gray-200 dark:border-gray-700">
<div class="flex items-center flex-1">
<div class="md:ml-3">
<SelectAllDropdown
v-if="shouldShowCheckBoxes"
:all-matching-resource-count="allMatchingResourceCount"
:current-page-count="currentPageCount"
@toggle-select-all="toggleSelectAll"
@toggle-select-all-matching="toggleSelectAllMatching"
@deselect="$emit('deselect')"
/>
</div>
<div class="flex items-center pr-2 md:pr-3">
<!-- ...existing code... -->
<div class="h-9 ml-auto flex items-center">
<div class="hidden md:flex px-2">
<label for="itemsPerPage" class="sr-only">Items Per Page</label>
<select
id="itemsPerPage"
class="rounded-md border-gray-300 dark:border-gray-600 focus:border-primary-500 focus:ring focus:ring-primary-200 dark:focus:ring-gray-600"
v-model="itemsPerPage"
@change="onItemsPerPageChange"
>
<option value="10">10 per page</option>
<option value="20">20 per page</option>
<option value="50">50 per page</option>
<option value="100">100 per page</option>
</select>
</div>
</div>
</div>
<!-- <div class="h-9 ml-auto flex items-center pr-2 md:pr-3"><div class="hidden md:flex px-2"><!––></div><!––><!––><div class="flex h-9 hover:bg-gray-100 dark:hover:bg-gray-700 rounded" dusk="filter-selector"><button aria-expanded="false" class="rounded active:outline-none active:ring focus:outline-none focus:ring focus:ring-primary-200 dark:focus:ring-gray-600" type="button"><span class="sr-only">Filter Dropdown</span><div class="toolbar-button flex items-center cursor-pointer select-none toolbar-button px-2"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="24" height="24" class="inline-block" role="presentation"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"></path></svg><!––><svg class="flex-shrink-0 ml-2" xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6"><path class="fill-current" d="M8.292893.292893c.390525-.390524 1.023689-.390524 1.414214 0 .390524.390525.390524 1.023689 0 1.414214l-4 4c-.390525.390524-1.023689.390524-1.414214 0l-4-4c-.390524-.390525-.390524-1.023689 0-1.414214.390525-.390524 1.023689-.390524 1.414214 0L5 3.585786 8.292893.292893z"></path></svg></div></button></div><!––></div>
--> </div>
</div>
<LoadingView :loading="loading">
<table class="w-full divide-y divide-gray-100 dark:divide-gray-700"
data-testid="resource-table">
<thead class="bg-gray-50 dark:bg-gray-800">
<tr>
<th class="td-fit uppercase text-xxs text-gray-500 tracking-wide pl-5 pr-2 py-2"><span class="sr-only">Selected Resources</span></th>
<th class="text-left px-2 whitespace-nowrap uppercase text-gray-500 text-xxs tracking-wide py-2">ID</th>
<th class="text-left px-2 whitespace-nowrap uppercase text-gray-500 text-xxs tracking-wide py-2">Headline</th>
<th class="text-left px-2 whitespace-nowrap uppercase text-gray-500 text-xxs tracking-wide py-2">Start Date</th>
<th class="text-left px-2 whitespace-nowrap uppercase text-gray-500 text-xxs tracking-wide py-2">End Date</th>
</tr>
</thead>
<tbody v-if="items.data && items.data.length > 0" class="divide-y divide-gray-100 dark:divide-gray-700">
<tr class="group" v-for="(item, index) in items.data" :key="index">
<td class="py-2 cursor-pointer td-fit pl-5 pr-5 dark:bg-gray-800 group-hover:bg-gray-50 dark:group-hover:bg-gray-900"><input type="checkbox" class="checkbox" aria-label="Select Resource 1" data-testid="adverts-items-0-checkbox" dusk="1-checkbox"></td>
<td class="px-2 py-2 whitespace-nowrap cursor-pointer dark:bg-gray-800 group-hover:bg-gray-50 dark:group-hover:bg-gray-900">
<div class="text-left"> <span class="whitespace-nowrap">{{ item.id }}</span></div>
</td>
<td class="px-2 py-2 whitespace-nowrap cursor-pointer dark:bg-gray-800 group-hover:bg-gray-50 dark:group-hover:bg-gray-900">{{ item.headline }}</td>
<td class="px-2 py-2 whitespace-nowrap cursor-pointer dark:bg-gray-800 group-hover:bg-gray-50 dark:group-hover:bg-gray-900">{{ item.start_date }}</td>
<td class="px-2 py-2 whitespace-nowrap cursor-pointer dark:bg-gray-800 group-hover:bg-gray-50 dark:group-hover:bg-gray-900">{{ item.end_date }}</td>
</tr>
</tbody>
</table>
<div class="border-t border-gray-200 dark:border-gray-700">
<ROPagination :data="items" @pagination-change-page="getAdverts" />
</div>
</LoadingView>
</Card>
</div>
</template>
<script>
//import { TailwindPagination } from 'laravel-vue-pagination';
import ROPagination from "../components/ROPagination.vue";
export default {
name: "Manager",
components: {
ROPagination
},
props: {
shouldShowCheckBoxes: {
type: Boolean,
default: true,
},
currentPageCount: {
type: Number,
default: 0
},
allMatchingResourceCount: {
type: Number,
default: 0
},
shouldShowActionSelector : {
type: Boolean,
default: true,
}
},
data() {
return {
items: {},
loading:false,
createButtonLabel: 'Create New Advert',
searchPlaceholder: 'Search Adverts',
singularName: 'Advert',
resourceName: 'Adverts',
itemsPerPage: 10 // Add this line to define the itemsPerPage property
};
},
mounted() {
this.getAdverts();
},
methods: {
getAdverts(page = 1, perPage ) {
this.loading = true;
Nova.request().get('/nova-vendor/manager/index?page='+ page + '&perPage=' + perPage)
.then(response => {
this.items = response.data;
this.loading = false;
})
.catch(error => {
console.log(error);
});
},
onItemsPerPageChange() {
// Call the getAdverts method with the updated itemsPerPage value
this.getAdverts(1, this.itemsPerPage);
},
computed: {
/**
* Return the heading for the view
*/
headingTitle() {
return 'Adverts'
},
}
}
}
</script>
<style>
/* Your custom styles here */
</style>
下面是ROPagination组件
<RenderlessPagination
:data="data"
:limit="limit"
:keep-length="keepLength"
@pagination-change-page="onPaginationChangePage"
>
<template #default="slotProps">
<div class="rounded-b-lg">
<nav class="flex justify-between items-center"
v-bind="$attrs"
aria-label="Pagination"
v-if="slotProps.computed.total > slotProps.computed.perPage"
>
<button
:class="{
'text-xs font-bold py-3 px-4 focus:outline-none rounded-bl-lg focus:ring focus:ring-inset text-primary-500 hover:text-primary-400 active:text-primary-600': slotProps.computed.prevPageUrl,
'text-xs font-bold py-3 px-4 focus:outline-none rounded-bl-lg focus:ring focus:ring-inset text-gray-300 dark:text-gray-600': !slotProps.computed.prevPageUrl
}"
:disabled="!slotProps.computed.prevPageUrl"
v-on="slotProps.prevButtonEvents"
>
<slot name="prev-nav">
Previous
</slot>
</button>
<span class="text-xs px-4">
{{ currentPageRange(slotProps.computed) }}
</span>
<button
:class="{
'text-xs font-bold py-3 px-4 focus:outline-none rounded-br-lg focus:ring focus:ring-inset text-primary-500 hover:text-primary-400 active:text-primary-600': slotProps.computed.nextPageUrl,
'text-xs font-bold py-3 px-4 focus:outline-none rounded-bl-lg focus:ring focus:ring-inset text-gray-300 dark:text-gray-600': !slotProps.computed.nextPageUrl
}"
:disabled="!slotProps.computed.nextPageUrl"
v-on="slotProps.nextButtonEvents"
>
<slot name="next-nav">
Next
</slot>
</button>
</nav>
</div>
</template>
</RenderlessPagination>
</template>
<script>
import RenderlessPagination from 'laravel-vue-pagination/src/RenderlessPagination.vue';
export default {
inheritAttrs: false,
emits: ['pagination-change-page'],
components: {
RenderlessPagination,
},
props: {
data: {
type: Object,
default: () => ({}),
},
limit: {
type: Number,
default: 0,
},
keepLength: {
type: Boolean,
default: false,
},
},
methods: {
onPaginationChangePage(page) {
this.$emit('pagination-change-page', page);
},
currentPageRange(computed) {
const currentPage = computed.currentPage;
const perPage = computed.perPage;
const total = computed.total;
if (total === 0) {
return '';
}
const start = (currentPage - 1) * perPage + 1;
const end = Math.min(currentPage * perPage, total);
return `${start}-${end} of ${total}`;
},
},
};
</script>
这是我的Laravel控制器
namespace Atz\Manager\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Tenant\Advert;
class ManagerController extends Controller
{
/**
* Get initial advert data for the manager tool.
*
* @return
*/
public function index(\Illuminate\Http\Request $request)
{
$perPage = $request->input('perPage', 10);
$adverts = Advert::paginate($perPage);
return response()->json($adverts);
}
1条答案
按热度按时间y0u0uwnf1#
你的控制器看起来对我来说,你确定你在“getAdverts”方法中正确地传递了Nova请求中的GET参数吗?简单地在get()函数中“硬编码”URL可能会导致一些错误。
我不熟悉Nova请求,但对于axios,它的工作方式类似,您将route get参数作为get()函数中的第二个参数传递。
即
axios.get('your/url/here, { 'perPage': variable })
。您可以尝试在控制器中添加
dd($request->all()
,以查看GET参数'perPage'是否传递给控制器。