ElpsySec's avatar

Simple Route Params Binding With Vue.js

I have a table component that relies on pagination to display a chunk at a time. While I am using the paginate() feature, I am not using laravel to update the route because I'm using vue-resource. I was wondering if there was a simple way to bind a data property to a route paramater such as page. I'm also passing in sort and search parameters in the route.

I've looked at vue-router, but I dont' know if that is the best solution for my use case as I am not using a single page application. Basically I'm just trying to bind route parameters.

Any advice is appreciated. Thanks!

0 likes
13 replies
infernobass7's avatar

Here isa component that I used for a pagination in Vue. It passes the current page up to the chain to then filter the items shown with limitBy in the parent component. It also uses Bootstrap pagination classes for styling. Hopefully this helps.

<template>
    <ul class="pagination">

        <li v-if="active > 3">
            <a href="#" @click.stop.prevent="update(0)">{{ 1 }}</a>
        </li>

        <li v-if="active > 3" class="disabled">
            <a href="#">...</a>
        </li>

        <li v-for="n in numbers" :class="{'active' : n == active}">
            <a href="#" @click.stop.prevent="update(n)">{{ n+1 }}</a>
        </li>

        <li v-if="active < length-4" class="disabled">
            <a href="#">...</a>
        </li>

        <li v-if="active < length-4">
            <a href="#" @click.stop.prevent="update(length)">{{ length+1 }}</a>
        </li>

    </ul>
</template>

<script>

    export default{
        data(){
            return{
                n: 0,
                active: 0
            }
        },

        props:['items', 'count', 'type'],

        computed: {
            length: function() {
                return Math.ceil(this.items.length / this.count);
            },

            min: function() {
                if(this.active < 4) {
                    return 0;
                } else if ( this.active > this.length - 7) {
                    return this.length-7;
                } else  {
                    return this.active-2;
                }
            },

            max: function() {
                if (this.length < 7) {
                    return this.length;
                } else if(this.active < 4) {
                    return 7;
                } else if ( this.active > this.length - 7) {
                    return this.length;
                } else  {
                    return this.active+3;
                }
            },

            numbers: function() {
                var temp = [];
                for(var i = this.min; i < this.max; i++) {
                    temp.push(i);
                }
                return temp
            }
        },

        methods: {
            update: function(n){
                this.active = n;
                this.$dispatch('page-' + this.type, this.active);
            }
        }
    }
</script>
infernobass7's avatar

Yes I have a working example for this. However, it on a non-public server :( Are you having trouble with some thing in this component?

dawiyo's avatar

I was having trouble getting the referenced items being paginated to update. I'm still new to Vue and I guess I'm still thinking in an Angular kind of way.

infernobass7's avatar

@dawiyo Check this out: http://jsbin.com/dacehocuju/1/edit?html,js,output

  • I added the limitBy function to your item v-for that hides items not currently being displayed. Since you only had 12 items I used a limit of 5 to force it to display 3 links.
  • I added some variables that your parent component (or root like it is set up in the jsbin) that were missing.
  • A very important item to note is when you define the pagination item, when you try to pass an object to the component you need to use : this tells vue to pass the variable and not just the string.
  • Lastly, your parent component or root needs an event that is named 'page-{type}', where {type} is the type specified when you created the pagination item. The function here catches the notice that the pagination item transmits when the link is clicked and updates variables in the parent.

If there are any console.log()'s left in, you may want to delete them.

dawiyo's avatar

Your'e the man @infernobass7. I think this needs to be a Vue package cause I sure couldn't find one with the page numbers.

infernobass7's avatar

Yeah. I found one package but it was not pretty and did not work. So I created my own. I will see about putting it up on Github for people to use.

dawiyo's avatar

Sorry to keep blowing up your post OP but @infernobass7, there's a small bug in the page numbering. It adds an extra page after the last page is offset with results.

Please or to participate in this conversation.