Is there a way to make a loop to create objects in Vue3?

You can run any valid javascript code inside the <script> tag, so this will work

<script>

const initialBoard = []
for (var i = 1; i <= 50; i++) {
  initialBoard.push({number: i, isclicked: false});
}

export default {
  name: "App",
  components: {},

  data() {
    return {
      boardfields: initialBoard
    };
  },

@Daniel - thanks for the clarification. Upvote for Boussadjra Brahim's answer which is better.


Use a "factory" function to create the data if you wish to have independent boardfields per component.

<script>

const initializeBoard = () => {
  const initialBoard = [];
  for (var i = 1; i <= 50; i++) {
    initialBoard.push({number: i, isclicked: false});
  }
  return initialBoard;
}

export default {
  name: "App",
  components: {},

  data() {
    return {
      boardfields: initializeBoard()
    };
  },

I think @Boussadjra's answer is correct, but wanted to add some context.

The functional [...Array(50)].map()...etc is the popular way to go these days. You can populate the value on data definition or onmount or oncreate, there are some nuances that might be worthwhile considering.

Note that if you are using:

const initialBoard = []
for (var i = 1; i <= 50; i++) {
  initialBoard.push({number: i, isclicked: false});
}

export default {
  name: "App",
  components: {},

  data() {
    return {
      boardfields: initialBoard
    };
  },
}

The value of initialBoard is persistent. The objects are created on first run and are populating the array which is re-used. That means if you create two components, they may share the values of the objects inside the array. IMHO, this is a a side effect you want to avoid unless you explicitly looking for that functionality, even if you only use one instance of the component.

B's solution...

export default {
  name: "App",
  components: {},

  data() {
    return {
      boardfields: [],
    };
  },
  mounted() {
    this.boardFields=[...Array(50)].map((_,i)=>({number: i+1, isclicked: false}))
  }
}

Is safer in that regard, since it generates a new array with new objects every time it is mounted. My preference would be to use created, because it will make the data available on the first draw, but because the variable is preset to an empty array, it's not going to cause errors (like an error in your template if the variable had .length on undifined or null)

Here is an example that illustrates the difference. Not that when the component is remounted or recreated (doesn't make a difference which on here) the data is lost, but the (top) two components don't share the data., wheras the bottom two do.

const app = Vue.createApp({
  data: function() {
    return {
      cKey: 1
    }
  }
})

const prepArr = [...Array(5)].map((_, i) => ({
  name: 'item-' + i
}))

app.component("my-component", {
  data: function() {
    return {
      myArr: []
    }
  },
  created: function() {
    this.myArr = [...Array(5)].map((_, i) => ({
      name: 'item-' + i
    }))
  },
  template: `<div class="h">Component Using created<ul>
    <li v-for="item in myArr">{{ item.name }} <button  @click="()=>{item.name = item.name +'!'}">+</button></li>
  </ul></div>`
});


app.component("persistent-component", {
  data: function() {
    return {
      myArr: prepArr
    }
  },
  template: `<div class="h">Component using persistent<ul>
    <li v-for="item in myArr">{{ item.name }} <button  @click="()=>{item.name = item.name +'!'}">+</button></li>
  </ul></div>`
});


app.mount('#app')
.h{display: inline-block; width: 49%;}
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>

<div id="app">
  <div><button @click="()=>{cKey++}">regenerate</button></div>
  <my-component :key="cKey"></my-component>
  <my-component :key="cKey"></my-component>
  <persistent-component :key="cKey"></persistent-component>
  <persistent-component :key="cKey"></persistent-component>
</div>


You could achieve this by using [...Array(50)] which returns 50 items with undefined values then map this array to return your objects array, this is done in the mounted lifecycle hook :

export default {
  name: "App",
  components: {},
  data() {
    return {
      boardfields: [],
    };
  },
  mounted(){
    this.boardFields=[...Array(50)].map((_,i)=>({number: i+1, isclicked: false}))
  }
}

Tags:

Vue.Js

Vuejs3