Search code examples
phplaravelvue.jsvue-componentvue-resource

How to make Custom Pagination Component Using Laravel and Vue Js


I am using Laravel and Vue Js for the data listing and paginate data using vue component, without using component my code works fine but when i use component pagination bar is working but not sync with listing,

Here is my Html

<!DOCTYPE html>
<html>
<head>
	<title>Users List</title>
	<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.css">
</head>
<body>

	<div class="container" id="users">


		<!-- Item Listing -->
		<table class="table table-bordered">
			<tr>
				<th>Name</th>
				<th>Email</th>
				<th>Created At</th>
			</tr>
			<tr v-for="user in users">
				<td>@{{ user.name }}</td>
				<td>@{{ user.email }}</td>
				<td>@{{ user.created_at }}</td>
			</tr>
		</table>

  		<vue-pagination></vue-pagination>

	</div>

	<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
	<script type="text/javascript" src="https://cdn.jsdelivr.net/vue.resource/0.9.3/vue-resource.min.js"></script>
	<script type="text/javascript" src="/js/users.js"></script>
</body>
</html>

And Here is my Vue Js Code

var VueComponent  = Vue.extend({
  template: 
        '<nav>' +
          '<ul class="pagination">' +
              '<li v-if="pagination.current_page > 1">' +
                  '<a href="#" aria-label="Previous" @click.prevent="changePage(pagination.current_page - 1)">' +
                      '<span aria-hidden="true">«</span>' +
                  '</a>' +
              '</li>' +
              '<li v-for="page in pagesNumber" :class="{\'active\': page == pagination.current_page}">' +
                  '<a href="#" @click.prevent="changePage(page)">{{ page }}</a>' +
              '</li>' +
              '<li v-if="pagination.current_page < pagination.last_page">' +
                  '<a href="#" aria-label="Next" @click.prevent="changePage(pagination.current_page + 1)">' +
                      '<span aria-hidden="true">»</span>' +
                  '</a>' +
              '</li>' +
          '</ul>' +
      '</nav>',

  props: ['user'],  

  data: function() {
    return {
      pagination: {
        total: 0, 
        per_page: 2,
        from: 1, 
        to: 0,
        current_page: 1
      },
      offset: 4,
    }
  },

  computed: {
        isActived: function () {
            return this.pagination.current_page;
        },
        pagesNumber: function () {
            if (!this.pagination.to) {
                return [];
            }
            var from = this.pagination.current_page - this.offset;
            if (from < 1) {
                from = 1;
            }
            var to = from + (this.offset * 2);
            if (to >= this.pagination.last_page) {
                to = this.pagination.last_page;
            }
            var pagesArray = [];
            while (from <= to) {
                pagesArray.push(from);
                from++;
            }
            return pagesArray;
        }
    },

  ready : function(){
      this.getUsers(this.pagination.current_page);
  },

  methods : {
    getUsers: function(page){
      this.$http.get('/user/api?page='+page).then((response) => {
        this.$set('pagination', response.data);
      });
    },

    changePage: function (page) {
      this.pagination.current_page = page;
      this.getUsers(page);
    }      
  }

})

Vue.component('vue-pagination', VueComponent);

new Vue({

  el: '#users',

  data: {
    users: [],
    pagination: {
        total: 0, 
        per_page: 2,
        from: 1, 
        to: 0,
        current_page: 1
      },
    offset: 4,
  },

  ready : function(){
  		this.getUsers(this.pagination.current_page);
  },

  methods : {
        getUsers: function(page){
          this.$http.get('/user/api?page='+page).then((response) => {
            this.$set('users', response.data.data);
          });
        },
  }

});

How to make this pagination work with vue js when using vue component Please Help me.


Solution

  • It is not that complicated. You just forgot to link your current page with your component. To do so , just change your code in HTML section

    <vue-pagination></vue-pagination>
    

    to

    <vue-pagination  :pagination="pagination" v-on:click="getUsers(pagination.current_page)"></vue-pagination>
    

    In your js code , get rid of data function from VueComponent and add pagination props

    .....
    props: {
            pagination: {
                type: Object,
                required: true
            }
        },
    computed: {
        pagesNumber: function () {
            if (!this.pagination.to) {
    ......
    

    Also, remove your getUsers method from VueComposent and combine with getUsers method in Vue main instance

    getUsers: function(page){
      this.$http.get('/user/api?page='+page).then((response) => {
         this.$set('users', response.data.data);
         this.$set('pagination', response.data);
      });
    

    I think, now your code should work as expected.