Cómo limitar la iteración de elementos en `v-for`

4 minutos de lectura

avatar de usuario
Nitish Kumar

Estoy construyendo una pequeña aplicación en Vuejs 2.0 Tengo aproximadamente 15 elementos iterativos. Quiero limitar el v-for por solo 5 elementos y puede tener más botones para mostrar la lista completa. ¿Hay alguna posibilidad?

  • muéstranos lo que has probado…

    – Muthu Kumaran

    07/10/2017 a las 16:00

  • ¿Posible duplicado de VueJs cómo hacer paginación con limitador y rango …?

    – Roy J.

    7 oct 2017 a las 16:18

avatar de usuario
Quoc-Anh Nguyen

Puedes probar este código

<div v-if="showLess">
    <div v-for="value in array.slice(0, 5)"></div>
</div> 
<div v-else> 
    <div v-for="value in array"></div>
</div> 
<button @click="showLess = false"></button>

Solo tendrá 5 elementos en la nueva matriz.

Actualización: pequeño cambio que hace que esta solución funcione tanto con matrices como con objetos

<div v-if="showLess">
  <div v-for="(value,index) in object">
    <template v-if="index <= 5"></template>
  </div>
</div> 
<div v-else> 
  <div v-for="value in object"></div>
</div> 
<button @click="showLess = false"></button>

  • Como se dijo, esto solo funciona en arregloslos objetos arrojarán errores.

    – Fusseldieb

    24 de agosto de 2018 a las 23:35


  • @Fusseldieb Sí… Por eso es muy buena práctica guardar sus datos como arreglos incluso cuando tienes datos como objeto. Te ayudará a trabajar con Vuejs de una mejor manera.

    – kuzey beytar

    1 de octubre de 2018 a las 8:11

  • o puede hacer una condición en el ciclo mismo <div v-for="value in (showLess ? array : array.slice(0, 5))></div> <button @click="showLess = false"></button>

    – arkadij_ok

    27 de noviembre de 2018 a las 6:16


  • es una mala práctica incluir v-if y v-for en el mismo elemento; intente evitar y agregue un contenedor con la condición v-if

    – YonatanAr

    27 de febrero de 2019 a las 13:18

  • @unplugged respuesta a continuación es la respuesta correcta, esta es una mala práctica

    – BritishSam

    28 de junio de 2020 a las 16:28

avatar de usuario
desenchufado

¿Estoy demasiado tarde? Puedes resolver esto usando propiedades calculadas:

<div v-for="value in computedObj">{{value}}</div>
<button @click="limit = null">Show more</button>

Luego en datos:

data(){
  return {
    object:[], // your original data
    limit: 5 // or any number you wish to limit to
  }
}

Y finalmente en sus propiedades calculadas:

computed:{
  computedObj(){
    return this.limit ? this.object.slice(0,this.limit) : this.object
  }
}

Cuando hace clic en el botón, el límite se borra y se muestran/devuelven todos los datos

Puedes probar esta solución para…

<div  class="body-table  div-table" v-for="(item,index) in items"  :key="item.id" v-if="items && items.length > 0 && index <= limitationList">....

y establece tu límite en datos

data() {
  return {
    limitationList:5
  };
},

y establecer una función en ti btn

  <button  @click="updateLimitation(limitationList)">
    show {{limitationList == 5 ? 'more' : 'less'}}
  </button>

y estos son tus metodos

updateLimitation(limitationList){
  if (this.limitationList == this.items.length) {
    this.limitationList = 5
  }else{
    this.limitationList = this.items.length
  }
}

espero te sea util…

  • Esta solución no es buena ya que el v-if de vue dejará un comentario en blanco para cada elemento que no pasó la verificación de límite. Entonces terminarás teniendo muchos “” en tu DOM.

    – Pinki Niza

    6 de febrero de 2018 a las 16:48

para resolver ese problema, puede calcular la lista de límites en el método calculado

como esto

<div  class="body-table  div-table" v-for="(item,index) in filterItems"  :key="item.id">
....

<script>

export default {
  data() {
     return {
       items: [],
       limitationList:5
    };
  },
  computed: {
    filterItems () {
      return this.items && this.items.length > 0 && (this.items.length - 1) <= this.limitationList  // or any condition u want 
    }
  }
}

</script>

Espero útil.

Esta es mi solución, verifique que si su lista de representación debe ocultar la sección raíz en la iteración <li>.

 <ul role="list">
     <li v-for="(actor,index) in this.cast" :key="actor.id" :class="{'your-hidden-class': index>5}">
       <div v-if="index <= 5">
         <img v-if="actor.profile_path" :src="'https://image.tmdb.org/t/p/original' + actor.profile_path" alt="" />
         <img v-else src="/images/image-not-found.png" alt="" />
         <div>
           <div>
             <h3>{{ actor.original_name }}</h3>
             <p>{{ actor.character }}</p>
           </div>
         </div>
       </div>
     </li>
 </ul>

avatar de usuario
Artur Muller Romanov

Esto es lo que computed fue hecho para (estoy usando script setup):

const paginatedList = computed(() => {
    // for arrays
    return yourArray.slice(0,5)

    // for objects/proxies such as reactive, refs, other computed
    // return yourObject.value.slice(0,5)
})

renderizarlo en un v-for círculo:

<div v-for="item in paginatedList">
    <p>{{ item }}</p>
</div

¿Ha sido útil esta solución?