<section class="banner-store">
  <h3>Banner</h3>
</section>
<div id="app" class="container-lg">
  <div class="d-flex flex-column flex-md-row row">
    <div class="col-12 col-md-3 ">
      <div v-if="uniqueCheckboxes" v-for="(value, key) in uniqueCheckboxes" class="input-checkbox ">
        <input @change="setCheckBoxFilters(key)" type="checkbox" :id="'brand-' + key" :value="key">
        <label :for="'brand-' + key">
          <span></span>
          {_ key _}
          <small>{_ value _}</small>
        </label>
      </div>
    </div>
    <div class="col-12 col-md-9 row ">
      <div v-if="param && !displayedRecords.length ">Spiacenti non ci sono risultati per la tua ricerca, controlla la barra di ricerca</div>
      <transition-group tag="ul" class="content__list d-flex flex-wrap" name="company">
      <li v-for="(prodotto,index) in displayedRecords" :key='prodotto.id' class="p-2 company col-12 col-sm-12 col-md-3">
        <div>
          <div class="card">
            <img class="img-fluid" src="https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NHx8c2hvZXN8ZW58MHx8MHx8&auto=format&fit=crop&w=500&q=60" alt="" />
            <div class="card-body">
              <h6 class="card-title text-uppercase">{_ prodotto.title _}</h6>
              <div class="d-flex flex-column align-items-start justify-content-between">
                <small class="text-uppercase card-text">With supporting</small>
                <small class="ms-auto text-uppercase">Shop now</small>
              </div>
            </div>
          </div>
        </div>
      </li>
       </transition-group>
      <nav aria-label="Page navigation example">
        <ul class="pagination">
          <li class="page-item">
            <button type="button" class="page-link" v-if="page != 1" @click="page--"> Previous </button>
          </li>
          <li class="page-item d-flex">
            <button type="button" class="page-link" v-for="pageNumber in pages.slice(page-1, page+5)" @click="page = pageNumber"> {_ pageNumber _} </button>
          </li>
          <li class="page-item">
            <button type="button" @click="page++" v-if="page < pages.length" class="page-link"> Next </button>
          </li>
        </ul>
      </nav>
    </div>
  </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  new Vue({
    el: "#app",
    delimiters: ["{_", "_}"],
    data: function() {
      return {
        prodotti: [],
        perPage: 20,
        page: 1,
        pages: [],
        param: null,
        computedLength: null,
        min: null,
        max: null,
        checkBoxFilters: [],
        instance: null
      }
    },
    methods: {
      setCheckBoxFilters(valueItem) {
        if (!this.checkBoxFilters.includes(valueItem)) {
          // ✅ only runs if value not in array
          this.checkBoxFilters.push(valueItem.toLowerCase());
          console.log(this.checkBoxFilters);
        } else
          this.checkBoxFilters = this.checkBoxFilters.filter(function(el) {
            return el != valueItem;
          });
        console.log(this.checkBoxFilters);
      },
      setPages() {
        let numberOfPages = Math.ceil(this.prodotti.length / this.perPage);
        for (let index = 1; index <= numberOfPages; index++) {
          this.pages.push(index);
        }
      },
      paginate(posts) {
        let page = this.page;
        let perPage = this.perPage;
        let from = (page * perPage) - perPage;
        let to = (page * perPage);
        return posts.slice(from, to)
      },
      getAllProducts() {
        fetch("https://dummyjson.com/products")
          .then((data) => data.json())
          .then(async (res) => (this.prodotti = await res.products))
          .catch((error) => console.error(error))
      }
    },
    async created() {
      await this.getAllProducts();
    },
    computed: {
      displayedRecords() {
        return this.checkBoxFilters.length ? this.paginate(this.prodotti.filter(el => this.checkBoxFilters.includes(el.category.toLowerCase()))) : this.paginate(this.prodotti)
      },
      uniqueCheckboxes() {
        const final = {};
        for (const {
            category
          } of this.prodotti) {
          final[category] = (final[category] || 0) + 1;
        }
        console.log(final);
        return final;
      },
    },
    watch: {
      prodotti() {
        this.setPages();
      }
    },
  })
</script>
/* base */
.company {
  backface-visibility: hidden;
  z-index: 1;
}

/* moving */
.company-move {
  transition: all 600ms ease-in-out 50ms;
}

/* appearing */
.company-enter-active {
  transition: all 400ms ease-out;
}

/* disappearing */
.company-leave-active {
  transition: all 200ms ease-in;
  z-index: 0;
}

/* appear at / disappear to */
.company-enter,
.company-leave-to {
  opacity: 0;
}
li {
list-style:none
}

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.8/vue.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.min.js