vue.js 如何获得每页的项目数以在分页中工作

8hhllhi2  于 2023-06-06  发布在  Vue.js
关注(0)|答案(1)|浏览(181)

我在我的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">&lt;!&ndash;&ndash;&gt;</div>&lt;!&ndash;&ndash;&gt;&lt;!&ndash;&ndash;&gt;<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>&lt;!&ndash;&ndash;&gt;<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>&lt;!&ndash;&ndash;&gt;</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);

    }
y0u0uwnf

y0u0uwnf1#

你的控制器看起来对我来说,你确定你在“getAdverts”方法中正确地传递了Nova请求中的GET参数吗?简单地在get()函数中“硬编码”URL可能会导致一些错误。
我不熟悉Nova请求,但对于axios,它的工作方式类似,您将route get参数作为get()函数中的第二个参数传递。
axios.get('your/url/here, { 'perPage': variable })
您可以尝试在控制器中添加dd($request->all(),以查看GET参数'perPage'是否传递给控制器。

相关问题