Является ли отзывчивая кладка с вкладками VueJS и Bootstrap даже возможной?

LiRa спросил: 13 июня 2018 в 09:29 в: javascript

Я использую VueJS для рендеринга динамических компонентов с переменной высотой в макете, но это часто приводит к уродливым пространствам, когда высота дон Совершенно отлично. Я надеялся использовать библиотеку, чтобы справиться с этим, но, к сожалению, ширина компонента вкладки также является переменной, что означает, что никто из них не работал адекватно.

Пример изображения

I имеют:

  • Vue 2.5
  • Bootstrap 3 (заблокирован, нет возможности обновить до 4)

Пример кода (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>

Я пробовал несколько разных библиотек кладки, но не имел успеха:

  • Масонство (jQuery) - не работает
  • Vue-Masonry (jQuery Masonry для VueJS) - работает при загрузке, но ломается при изменении ширины вкладки.
  • Salvattore (JS) - Не работает
  • Vue-Masonry-CSS (VueJS) - не работает (JSFiddle)

Я действительно не знаю, какие существуют другие хорошие решения для решения этой проблемы неудобное форматирование. Есть ли другой способ, чтобы мои элементы хорошо выравнивались в сетке?

1 ответ

LiRa ответил: 19 июня 2018 в 07:41

В конце концов я решил это, переключившись на два фиксированных столбца 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 для каждого столбца отдельно.

Дополнительное видео по вопросу: Является ли отзывчивая кладка с вкладками VueJS и Bootstrap даже возможной?

Bootstrap with Vue.js

Уроки Vue js практика - Task list

Vue.js - сборка с vue-cli и webpack [урок 5]