每个第6个循环元素的vue.js插入块

时间:2019-01-28 19:18:03

标签: javascript loops vue.js vue-component

我有整个循环提供卡片清单渲染。我在每个第3 col(bootstrap)元素中添加行div。现在,我需要为每个第6个元素添加另一个col元素(横幅块)。对于渲染这样的事情:

enter image description here

我该如何实现?

现在我的代码

<div class="row" v-for="i in Math.ceil(offers.length / 3)">
    <div class="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12" v-for="offer in offers.slice((i-1)*3, i*3)">
        <h2>{{offer.name}}</h2>
        <h2>{{offer.desc}}</h2>
    </div>
</div>

7 个答案:

答案 0 :(得分:3)

这应该完全满足您的要求。.我不得不对数据进行一些操作,因为Vue的模板语言并非旨在处理这种用例的逻辑

HTML

ID| SEQ | TYPE | SUM(VAL)
1 | 3   | A    | 200  <- 100 + 100
1 | 3   | B    | 200  
2 | 25  | X    | 150  <- 100 + 50
2 | 25  | Y    | 400

脚本

-- this sub query finds the max(seq) for each ID
with max_seq as (
  select id, max(seq) max_seq
  from my_table t
  group by id)
-- select query on my_table
select
  bd.id,
  bd.seq,
  bd.type,
  sum(bd.val)
from my_table bd
-- joining on id-max_seq pair
inner join max_seq 
  on 
  (max_seq.id = bd.id)
  and
  (max_seq.max_seq = bd.seq)
-- sum(val) per ID, MAX(SEQ), TYPE
group by bd.id, bd.seq, bd.type;

https://jsfiddle.net/jamesharrington/k6c0rgL3/17/

答案 1 :(得分:1)

我假设您想每6个元素添加一个横幅,但是您想显示第6个。我将在数据对象上处理此问题,并在其中插入横幅。更容易。您可以通过这种方式拆分阵列。

let firstPart = myData.slice(0,5)
let lastPart = myData.slice(5,)

let newData = [...firstPart, banner, ...lastPart]

现在,您只需每6个元素执行一次。

答案 2 :(得分:1)

for循环:

    <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>

对于每三个col可以使用css的新行

.mycol:nth-child(3n+1){
 clear:left;
}

答案 3 :(得分:1)

我建议您在视图中进行较少的编程,而在视图模型中进行更多的编程。创建一个computed,将您的数据分为一系列要约和横幅以及行,然后以简单的方式使用计算出的数据。

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);
  }
});
#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;
}
<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>

答案 4 :(得分:0)

我建议尽可能使用flex。 因此,代码如下所示: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;
    },
  },
});

答案 5 :(得分:0)

感谢大家,我采用了Roy J解决方案,针对我的情况进行了重建并获得了结果。我的代码:

<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>

答案 6 :(得分:-2)

我提供使用模板并在其上循环。 然后在内部检查v-if =“ i%6”->您的文章v-else->您的广告。