0

I'm trying to dynamically render a list of component objects in columns based on the size of the browser window. Right now, I have a computed property (columns) that calls my 'createColumns' function every time the number of columns changes. This works for rendering the columns correctly. The issue I'm having is with reactivity -- because I'm creating new lists (via array.slice), my items aren't being properly modified when I interact with them via the UI on the item component.

//computed
columns() {
  return this.createColumns(this.section.questions, this.numCols);
}

// method
createColumns(items, numCols) {
  const columns = [];
  for (let i = 0; i < numCols; i++) {
    const start = Math.ceil(i * (items.length / numCols));
    const end = Math.ceil(((i + 1) * items.length) / numCols);
    const colItems = items.slice(start, end);
    columns.push(colItems);
  }
  return columns;
}

In my html, I loop through my columns and render each component item.

<b-col
    v-for="(column, columnIndex) in columns"
    :key="`col-${columnIndex}`"
  >
    <item
      v-for="(item, index) in column"
      :key="item.key"
      :value="item"
    />
  </b-col>
</b-row>

What I want to be able to do is loop through sub-sections of my original items array and render the columns of items directly from that array rather than having to create new arrays containing a subsection of the data. I had originally tried using bootstrap-vue's row-cols feature but this results in a horizontal rendering of the items, i.e.

1 2 3
4 5 6
7 8 9

Instead of

1 4 7
2 5 8
3 6 9

Which is what I'm going for

Paul Murray
  • 399
  • 2
  • 16
  • Perhaps you should be using CSS columns (https://developer.mozilla.org/en-US/docs/Web/CSS/columns) which will render top to bottom, then left to right. This will keep the order in the rendered HTML semantic for keyboard only users. You can create media queries to adjust the number of CSS columns based on viewport width. The only issue with this would be not all "cells" may not be the same height. – Troy Morehouse Feb 11 '20 at 20:03
  • That's working much better, thanks! I set a fixed height on my items so that shouldn't be an issue. Is there a way to still use bootstrap's alignment utilities with CSS columns? justify-content-between on the row no longer works now that there's only one column being rendered – Paul Murray Feb 11 '20 at 20:23
  • Since columns render top to bottom, then left to right (after the browser figures out the needed total height), flex alignment utilities will not work on them. You can make each "cell" (items) a `d-flex` display and then apply any of the flex utility classes on the item (or item content). Just don't use `` or `` in this case. – Troy Morehouse Feb 11 '20 at 20:35

0 Answers0