6

What is the best way to create a grid dynamically with Vue?

I was thinking of using the v-for loop to generate cards on a page for X number of 'modules', but would like to arrange them in rows of 3.

e.g

 Card | Card | Card
 Card | Card | Card
3
  • 1
    posible solutions, uses computed property to reshape your 1D array to 2D array. then v-for twice. or v-for your 1D array with display:flex and its children with something like flex: 0 0 33.333% Commented Aug 28, 2018 at 23:04
  • using CSS grids is a possible solution (ex -> display:grid; grid-template-columns:1fr 1fr 1fr); Commented Aug 29, 2018 at 3:31
  • @Sphinx Thank you, I like the 'flex: 0 0 33.33%' solution. Commented Aug 29, 2018 at 9:11

1 Answer 1

23

You can use CSS grid layout, make sure to check browser support.

We'll need to make the container a grid container using display: grid and use grid-template-columns.

You can create a component that accepts a number prop and then use it in the repeat() notation.

repeat({numberOfColumns}, minmax({minColumnSize}, {maxColumnSize}))

new Vue({
  el: "#app",
  data() {
    return {
      cards: [1, 2, 3, 4],
      numberOfColumns: 3,
    }
  },
  computed: {
    gridStyle() {
      return {
        gridTemplateColumns: `repeat(${this.numberOfColumns}, minmax(100px, 1fr))`
      }
    },
  },
  methods: {
    addCard() {
      this.cards.push('new-card')
    },
  },
})

Vue.config.productionTip = false;
Vue.config.devtools = false;
.card-list {
  display: grid;
  grid-gap: 1em;
}

.card-item {
  background-color: dodgerblue;
  padding: 2em;
}

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

ul {
  list-style-type: none;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  Columns: <input v-model.number="numberOfColumns">
  <ul :style="gridStyle" class="card-list">
    <li v-for="(card, index) in cards" class="card-item">
      {{ index + 1 }}
    </li>
  </ul>
  <button @click="addCard">
    Add card
  </button>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.