0

I am trying to create pagination component. For e.g if my API returns "pages": 9

For example, if I have 9 pages, I want to cut the list at 5 and add three dots like on the image. I want to be able to provide at which index I can cut the list. Whats the best way to do this? I am approaching this wrong?

enter image description here

<div v-for="index in pages" class="flex">
<button>{{index}}</button>
</div>
2
  • vue2 or vue3? Commented Jul 30, 2021 at 9:29
  • @User10519069 vue 3 Commented Jul 30, 2021 at 9:31

2 Answers 2

1

Assuming you receive cutIndex and apiPages as props to your component, then your template could look something like the following:

<div v-for="page in Math.min(cutIndex, apiPages)" class="flex">
  <button>{{page}}</button>
</div>
<template v-if="cutIndex < apiPages">
  <div class="flex">
    <button>...</button>
  </div>
  <div class="flex">
    <button>{{apiPages}}</button>
  </div>
</template>
Sign up to request clarification or add additional context in comments.

Comments

0

this code works for me, and here is the key part

<template>
        ...
        <template v-for="index in pages"
            v-if="(index < 4 || (length - index) < 3) || Math.abs(index - value) < 2">
            <span v-if="index === (length - 2) && value < (length - 4)">
                ...
            </span>
            <button @click.prevent="updatePage(index)">
                {{ index }}
            </button>
            <span v-if="(index === 3 && value > 5)">
                ...
            </span>
        </template>
        ...
</template>

the result:

enter image description here

<template>
    <nav class="flex items-center justify-center" role="pagination">
        <!-- go to previous page -->
        <a :key="`${$route.name}-arrow-${value > 1 ? value - 1 : 1}`"
            :href="getFullPath(value > 1 ? value - 1 : 1)"
            :title="$t('previous_page')"
            @click.prevent="updatePage(value > 1 ? value - 1 : 1)"
            :disabled="value === 1"
            class="arrow pop-btn default rounded-sm"
            v-waves>
            <i class="mdi-chevron-left mdi"></i>
        </a>

        <template v-for="index in length"
            v-if="(index < 4 || (length - index) < 3) || Math.abs(index - value) < 2">
            <span v-if="index === (length - 2) && value < (length - 4)">
                ...
            </span>
            <a :href="getFullPath(index)"
                :title="$t('page_index', {index: index})"
                @click.prevent="updatePage(index)"
                class="pop-btn number default rounded-sm"
                :class="{
                    'active': index === value
                }"
                v-waves>
                {{ index }}
            </a>
            <span v-if="(index === 3 && value > 5)">
                ...
            </span>
        </template>

        <!-- go to next page -->
        <a :href="getFullPath(value === length ? value : value + 1)"
            :title="$t('next_page')"
            @click.prevent="updatePage(value === length ? value : value + 1)"
            :disabled="value === length"
            class="arrow pop-btn default rounded-sm"
            v-waves>
            <i class="mdi-chevron-right mdi"></i>
        </a>

    </nav>
</template>
<script type="text/javascript">
export default{
    emits: ['update:value],
    props: {
        length: {
            required: true,
            type: Number
        },
        // the page filter
        value: {
            required: true,
            type: Number
        }
    },
    methods: {
        updatePage(index){
            this.$emit('update:value', index);
        },
        getFullPath(page){
            let query = {...this.$route.query};
            page === 1 ? delete query.page : query.page = page;
            return this.$router.resolve(
                this.r({
                    query: query,
                    name: this.$route.name,
                    params: this.$route.params
                })
            ).href;
        }
    }
}
</script>

by the way, <a> may better than <button> for SEO

2 Comments

Just a note on v-for and v-if, it is not recommended to use them on the same element - v3.vuejs.org/style-guide/#avoid-v-if-with-v-for-essential
thanks a lot! I just copy them from my old project which is coded in nuxt 😅

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.