使用 VueJS 和 Bootstrap 选项卡的响应式砌体甚至可能吗?

Is responsive masonry with VueJS and Bootstrap Tabs even possible?

我正在使用 VueJS 在 "masonry" 布局中呈现具有可变高度的动态组件,但是当高度未完全对齐时,这通常会产生丑陋的空间。我希望使用一个库来处理这个问题,但不幸的是,选项卡组件的宽度也是可变的,这意味着 none 它们可以正常工作。

Example Image

我有:

示例代码 (JSFiddle):

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<div id="app" class="container">
    <button v-on:click="currentWidth += 50">Increase Parent Width</button>
    <button v-on:click="currentWidth -= 50">Decrease Parent Width</button>
    <div class="parent pt1" v-bind:style="{width: currentWidth + 'px'}">
        <ul class="nav nav-tabs" role="tablist">
            <li v-for="(tab, tabIndex) in tabs" role="presentation" v-bind:class="{active: tabIndex == selectedTab}">
                <a v-bind:href="tab.name" role="tab" data-toggle="tab" v-on:click="selectedTab = tabIndex">{{tab.name}}</a>
            </li>
        </ul>
        <div class="tab-content">
            <div v-for="(tab, tabIndex) in tabs" role="tabpanel" v-bind:id="tab.name" class="tab-pane p1" v-bind:class="{active: tabIndex == selectedTab}">
                <div class="row">
                    <div v-for="dataPoint in tab.data" class="col-xs-6 blue">
                        <div class="green b1 vc text-center" v-bind:style="{height: randomHeight()}">
                            <h1>{{dataPoint}}</h1>
                        </div>
                        <br>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: function() {
      return {
        selectedTab: 0,
        currentWidth: 500,
        tabs: [{
          name: 'tab1',
          data: [1, 2, 3, 4, 5, 6, 7, 8, 9]
        }, {
          name: 'tab2',
          data: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
        }]
      }
    },
    methods: {
      randomHeight: function() {
        return ((Math.random() * 200) + 75) + 'px'
      }
    }
  })
</script>

<style>
  .p1{
    padding: 1em;
  }
  .pt1{
    padding-top: 1em;
  }
  .b1{
    border: 1px solid black;
  }
  .vc{
    display: flex;
    justify-content: center;
    flex-direction: column;
    text-align: center;
  }
  .blue{
    background-color: lightblue;
  }
  .green{
    color: black;
    background-color: lightgreen;
  }
</style>

我尝试了多个不同的砌体库,但都没有成功:

我真的不知道还有什么其他好的解决方案可以解决这种尴尬的格式问题。有没有其他方法可以让我的元素在网格中很好地对齐?

我最终通过切换到两个固定的 Bootstrap 列解决了这个问题,这意味着我可以用恰好一半的元素填充每一列。由于柱子没有堆叠在一起,所以一切都很好。

下面是一个示例,说明如何将要显示的元素数组拆分为两个:

splitItems: function(itemCategory) {
  let itemArray = Object.keys(this.items[itemCategory])
  let split = [[], []]
  let alternator = 0
  itemArray.forEach(item => {
    if (this.items[itemCategory][item] !== false) {
      split[alternator].push(item)
      alternator = Math.abs(alternator - 1)
    }
  })
  return split
}

然后您只需 运行 嵌套 v-for 以分别呈现每一列。