代码之家  ›  专栏  ›  技术社区  ›  Zeth

V-if inside V-for-在两列中显示项目列表

  •  2
  • Zeth  · 技术社区  · 7 年前

    • This
    • This 一种是使用两个不同的模板,编写 v-if 在模板标签上。在我的例子中,这似乎是愚蠢的,因为这两个模板将是98%相同的。
    • This 非常非常 离我很近。然而,-在他的例子中,这是对用户的过滤(由计算属性解决),而不是在某个迭代中插入代码片段的if子句(我想这就是我要找的)。

    问题

    -----------------
    | Item1   Item5 |
    | Item2   Item6 |
    | Item3   Item7 |
    | Item4         |
    -----------------
    

    我用一个 v-for

    我的尝试

    1. 使用纯CSS display: flex

    但这只能做到:

    -----------------
    | Item1   Item2 |
    | Item3   Item4 |
    | Item5   Item6 |
    | Item7         |
    -----------------
    
    1. column-count: 2;

    但那断柱中间的元素,就看了 display: block; overflow: hidden; 还有许多其他的尝试。应该说,这些元素的高度是可以变化的。

    1. 所以我放弃了用CSS来修复它。

    php ,然后我会简单地这样做:

    <?php
    if( $index == count( $items)/2 ):
      echo '</div>';
      echo '</div>';
      echo '<div class="col-md-6">';
      echo '<div class="item-container">';
    endif;
    ?>
    

    ... 但事实并非如此。我在找vue的替代品。我试过了 this :

    {{#if key === Number( items.length / 2 ) }}
      </div>
      </div>
      <div class="col-md-6">
      <div class="item-container">
    {{/if}
    

    有这样的事吗?

    我当前代码的简化

    <div class="col-md-12">
        <div class="items-container">
            <div class="item-container" v-for="item, key in items['data']">
                <!-- A BUNCH OF ITEM-INFO -->
            </div><!-- /.item-container -->
        </div><!-- /.items-container -->
    </div><!-- /.col-md-12 -->
    
    2 回复  |  直到 7 年前
        1
  •  9
  •   Phil    7 年前

    我要做的是创建一个computed属性,将items数组划分(或分块)为适当数量的列。

    下面是一个使用flexbox布局和一个额外的

    new Vue({
      el: 'main',
      data: {
        items: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6', 'Item 7'],
        cols: 2
      },
      computed: {
        columns () {
          let columns = []
          let mid = Math.ceil(this.items.length / this.cols)
          for (let col = 0; col < this.cols; col++) {
            columns.push(this.items.slice(col * mid, col * mid + mid))
          }
          return columns
        }
      }
    })
    .container {
      display: flex;
      border: 1px solid;
    }
    .col {
      margin: 10px;
      border: 1px solid;
      flex-grow: 1;
      display: flex;
      flex-direction: column;
    }
    .item-container {
      border: 1px solid;
      padding: 5px;
      margin: 5px;
    }
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script>
    <main>
    <p><label>Columns:<label> <input type="number" v-model="cols"></p>
    <div class="container">
      <div class="col" v-for="column in columns">
        <div class="item-container" v-for="item in column">{{item}}</div>
      </div>
    </div>
    </main>

    Split array into chunks

        2
  •  1
  •   keysl    7 年前

    很高兴看到有人偶然发现了和我一样的问题。我必须在每列中放置6个项目。我将API响应分为几列,然后打印出来。

    let allCategory = response.body.Categories.slice(); //clone
    while (allCategory.length > 0) {
      let chunk = allCategory.splice(0,6);
      this.ColArray.push(chunk);
    }  
    

    {
      ColArray: [
        Column1: [
          Item1,
          Item2,
          Item3,
        ],
        Column2: [
          ...
        ]
      ]
    }
    

    在Vue中,它将循环通过,如下所示:

    <div v-for="(col,colIndex) in ColArray" :key="'cate_col'+colIndex" class="col-md-2">
      <div v-for="(row,rowIndex ) in col"   :key="'cate_row'+colIndex + rowIndex" class="row">
        {{row}}
      </div>
    </div>
    

    这是一个提琴样本:

    https://jsfiddle.net/keysl183/50wL7mdz/775484/

        3
  •  0
  •   Aurinxki    6 年前

    此解决方案基于Phil的选定答案。

    它使用Object.keys循环对象,并使用Object.entries从对象返回数组。与其通过html模板中的索引进行访问,不如通过键进行访问。

    new Vue({
        el: 'main',
        data: {
            items: { 
              item1: { name: 'Item 1' }, 
              item2: { name: 'Item 2' }, 
              item3: { name: 'Item 3' },
              item4: { name: 'Item 4' },
              item5: { name: 'Item 5' },
              item6: { name: 'Item 6' },
              item7: { name: 'Item 7' },
              item8: { name: 'Item 8' },
              item9: { name: 'Item 9' },
              item10: { name: 'Item 10' },
            },
            cols: 2
        },
        computed: {
              columns: function() {
                  let columns = [];
                  let mid = Math.ceil(Object.keys(this.items).length / this.cols);
    
                  for (let col = 0; col < this.cols; col++) {
                      columns.push(Object.entries(this.items).slice(col * mid, col * mid + mid).map(entry => entry[1]));
                  }
                  return columns;
              }
          }
    });
    .container {
      display: flex;
      border: 1px solid;
    }
    .col {
      margin: 10px;
      border: 1px solid;
      flex-grow: 1;
      display: flex;
      flex-direction: column;
    }
    .item-container {
      border: 1px solid;
      padding: 5px;
      margin: 5px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script>
      <main>
        <p><label>Columns:<label> <input type="number" v-model="cols"></p>
        <div class="container">
          <div class="col" v-for="column in columns">
            <div class="item-container" v-for="(item, index) in Object.keys(column)">
            {{column[item].name}}</div>
          </div>
        </div>
    </main>
    推荐文章