1
votes

Please excuse my ignorance as a new web developer, but I can't seem to get the <b-paginate> component to work in my single file Django and Vue 2 app. I access Bootstrap Vue via CDN.

This is my component, which is placed directly above my main Vue app:

let paginationComponent = Vue.component('pagination-component', {
    name: 'paginationComponent',
    props:['pantryItems'],
    template:`<div class="overflow-auto"><b-pagination
      v-model="currentPage"
      :total-rows="rows"
      :per-page="perPage"
      first-text="First"
      prev-text="Prev"
      next-text="Next"
      last-text="Last"
      class="mt-4"
    ></b-pagination></div>`,
    
    data: function() {
      return {
        rows: this.pantryItems.length,
        perPage: 10,
        currentPage: 1,
      }

    },
    computed: {
        rows: function() {
            return this.pantryItems.length
        }
    }
})

and this is my Vue root app:

let mypantryapp = new Vue ({
    el: "#app",
    delimiters: ['[[', ']]'],
    components: {'pagination-component': paginationComponent},
    data: {
        pantryItems: [],
        name: '',
        users: [],
        itemName: '', 
        createdDate: '',
        expirationDate: '',
        csrf_token: '',
        itemErrors: {currentUser: false},
        currentUser: {id: false},
        owner: '',
        itemImgs: [],
        tags: [],
        by_category: false,
        grocery_view: false,

...followed by a bunch of unrelated methods for my pantry inventory app.

This is how I call it in my HTML:

<b-pagination :pantry-items='pantryItems' ></b-pagination>

The component renders on the page with just the number 1 in the middle of the pagination button group and all other buttons greyed out.

1

1 Answers

0
votes

The only mistake you've made here is confusing b-pagination for your own pagination-component child component.

You're invoking b-pagination perfectly in your template option, you just need to add the child component itself into your HTML to actually use it. The template parameter will replace the HTML of your child component in the DOM.

Simply change:

<b-pagination :pantry-items='pantryItems'></b-pagination>

to:

<pagination-component :pantry-items='pantryItems'></pagination-component>

And it should work correctly! Example below:

let paginationComponent = Vue.component('pagination-component', {
  name: 'paginationComponent',
  props: ['pantryItems'],
  template: `<div class="overflow-auto"><b-pagination
      v-model="currentPage"
      :total-rows="rows"
      :per-page="perPage"
      first-text="First"
      prev-text="Prev"
      next-text="Next"
      last-text="Last"
      class="mt-4"
    ></b-pagination></div>`,

  data: function() {
    return {
      //rows: this.pantryItems.length, *** See note below
      perPage: 1, //Lower perPage for example sake
      currentPage: 1,
    }

  },
  computed: {
    rows: function() {
      return this.pantryItems.length
    }
  }
});

let mypantryapp = new Vue({
  el: "#app",
  delimiters: ['[[', ']]'],
  components: {
    'pagination-component': paginationComponent
  },
  data: {
    pantryItems: [1, 2, 3, 4, 5], //Dummy items for example sake
  }
});
<!-- Set up Vue and Bootstrap-Vue for snippet -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap@4/dist/css/bootstrap.min.css" /><link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" /><script src="//unpkg.com/vue@latest/dist/vue.min.js"></script><script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>

<div id="app">
  <pagination-component :pantry-items='pantryItems'></pagination-component>
</div>

As one final note, you need only declare rows once. In this case, you should remove it from data, because it will change if your total items changes. Your computed rows will reflect the change, the rows var in data will not (since it will be set once at startup and then never again).