J'ai des offres de rendu de liste de cartes à travers la boucle. Tous les 3 éléments col (bootstrap), j'ajoute une ligne div. Maintenant, je dois ajouter un autre élément col (bloc de bannière) pour chaque 6ème élément. Pour rendre quelque chose comme ça:
Comment puis-je implémenter cela?
Mon code maintenant
< pré> XXX7 Réponses :
Cela devrait faire exactement ce que vous voulez .. J'ai dû manipuler les données car le langage de modélisation de Vue n'est pas conçu pour gérer la logique de ce type de cas d'utilisation
HTML
created () { while (this.items.length > 0) { const howMany = (this.rows.length % 3 === 0) ? 3 : 2 const row = this.items.splice(0, howMany) if (howMany === 2) row.push('banner') this.rows.push(row) } },
S'il fait cela, le 6e disparaîtra,
Mais qu'en est-il des lignes div conduisant pour chaque ligne 3d?
Je suis désolé, mais le 6ème élément sera remplacé par une bannière. Est-ce ce qu'il veut?
@RaphaelParreira Je l'ai changé pour que cela ne se produise pas, mais j'essaie de comprendre le problème des 3 par ligne
Ok je pense que je l'ai compris :)
Ne marche pas. Je pense parce que je reçois mes offres du serveur par axios (en méthode)
Ah ok bien vous pouvez simplement mettre cette boucle while créée dans la réponse de votre serveur
Parfait mais un dernier moment, la bannière n'a pas de paramètres d'offres (comme le nom, la description, l'url, etc.) que j'appelle en html {{offer.name}} ...
Je suppose que vous voulez ajouter une bannière tous les 6 éléments, mais vous voulez afficher le 6e. Je gérerais cela sur mon objet de données, en insérant la bannière à l'intérieur. C'est plus facile. Vous pouvez diviser votre tableau de cette façon.
let firstPart = myData.slice(0,5) let lastPart = myData.slice(5,) let newData = [...firstPart, banner, ...lastPart]
Maintenant, il vous suffit de le faire tous les 6 éléments.
pour la boucle:
.mycol:nth-child(3n+1){ clear:left; }
pour une nouvelle ligne pour chaque troisième col, vous pouvez utiliser css
<div class="mycol" v-for="(offer,ind) in offers"> <template v-if="ind % 5 == 0"> <h2>banner</banner> </template> <template v-else> <h2>{{offer.name}}</h2> <h2>{{offer.desc}}</h2> </template> </div>
c'est assez facile et simple,
Je vous recommande de faire moins de programmation dans la vue et plus dans le modèle de vue. Créez un calculé
qui divise vos données en séries d'offres et de bannières, ainsi qu'en lignes, puis utilisez-le de manière simple.
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script> <div id="app"> <div class="row" v-for="row in rows"> <div class="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12" v-for="item in row"> <div v-if="item.type === 'Banner'" class="banner box"> <h2>{{item.name}}</h2> </div> <div v-else class="offer box"> <h2>{{item.name}}</h2> </div> </div> </div> </div>
#app { display: grid; } .row { display: grid; grid-gap: 2rem; grid-template-columns: repeat(3, auto); justify-content: left; } .box { width: 8rem; height: 8rem; } .banner { background-color: #f9c; } .offer { background-color: #99f; }
const chunk = (arr, size) => arr .reduce((acc, _, i) => (i % size) ? acc : [...acc, arr.slice(i, i + size)], []); new Vue({ el: '#app', data: { offers: [] }, computed: { rows() { const withBanners = chunk(this.offers, 5).map((arr) => [...arr, {name: 'banner', type: 'Banner'}]).reduce((a, b) => a.concat(b), []); return chunk(withBanners, 3); } }, mounted() { setTimeout(() => { this.offers = [{ name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' }, { name: 'offer' } ]; }, 500); } });
Mais je reçois des offres du serveur via axios
Peu importe d'où vous l'obtenez. Le calcul sera correct lorsque les offres seront attribuées.
J'ai mis à jour l'extrait pour attribuer des offres après le démarrage du programme.
Et encore un problème, la bannière ne remplace pas (dans la requête) la 6ème offre et cette offre tombe dans une nouvelle ligne et j'ai 7 cols, pas 6. Plus la bannière s'ajoute à la fin, peu importe le nombre d'offres dans la liste
Ce sont toutes des choses que vous pouvez gérer dans le calcul. Faites-lui générer les données avec lesquelles vous souhaitez travailler.
Je recommande d'utiliser flex si c'est possible. Le code ressemblera donc à: http://jsfiddle.net/n89dbo37/
new Vue({ el: '#app', data() { return { items: _.times(20, i => ({type: 'offer'})), }; }, computed: { itemsWithBanners() { let result = []; this.items.forEach((item, idx) => { if (idx && idx % 5 === 0) { result.push({type: 'banner'}); } result.push(item); }); return result; }, }, });
Merci pour tout le monde, j'ai pris la solution Roy J, reconstruire pour mon cas et obtenir le résultat. Mon code:
<template> <div class="section-space80 results-col" > <div class="container" > <div class="row"> <div class="col-md-12"> <div class="wrapper-content bg-white pinside40"> <div class="row" v-for="row in rows"> <div v-for="offer in row" class="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12"> <div class="lender-listing" v-if="offer.type && offer.type === 'Banner'"> <div class="lender-head"> Banner </div> </div> <div class="lender-listing" v-if="offer.mfoName"> <div class="lender-head"> <div class="lender-logo">Offer</div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </template> <script> const chunk = (arr, size) => arr .reduce((acc, _, i) => (i % size) ? acc : [...acc, arr.slice(i, i + size)], []); import axios from 'axios' export default { data() { return { showOffers: true, loanOffers: [], isVisible: false, loadMore: true, offset: 0, rows: '' } }, methods: { getOffersList: function () { let dataElements = this dataElements.loading = true axios.get('/api/v1/getUserOffers') .then(function (response) { dataElements.loanOffers = response.data const withBanners = chunk(dataElements.loanOffers, 5).map((arr) => [...arr, {name: 'banner', type: 'Banner'}]).reduce((a, b) => a.concat(b)); dataElements.rows = chunk(withBanners, 3); }) }, }, beforeMount(){ this.getOffersList() } } </script>
Je propose d'utiliser un modèle et de faire une boucle dessus. Ensuite, à l'intérieur, vous vérifiez v-if = "i% 6" -> votre article v-else -> votre annonce.
Veuillez fournir un exemple de code