Vue3中有没有办法循环创建对象?

问题描述 投票:0回答:3
<template>
  <div class="container">
    <div class="gameboard">
      <div v-for="item in boardfields" :key="item.number">
        {{ item.number }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},

  data() {
    return {
      boardfields: [
        { number: 1, isclicked: false },
        { number: 2, isclicked: false },
        { number: 3, isclicked: false },
        { number: 4, isclicked: false },
        { number: 5, isclicked: false },
        { number: 6, isclicked: false },
      ],
    };
  },

如您所见,我在“boardfields”数组中有一些类似的对象。我必须做大约 50 个。有没有办法创建一个循环,用不同的数字创建一定数量的该对象并将其推送到数组,这样我就不必复制和粘贴它并手动更改数字?

我认为在 JS 中会是这样的

var i;
for (var i = 0, i > 50, i++){
  this.boardfields.push({number: i, isclicked: false});
}
vue.js vuejs3
3个回答
4
投票

我认为@Boussadjra的答案是正确的,但想添加一些上下文。

功能性

[...Array(50)].map()...etc
是当今流行的方式。您可以填充数据定义上的值或
onmount
oncreate
,有一些细微差别可能值得考虑。

请注意,如果您正在使用:

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

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

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

initialBoard
的值是持久。这些对象是在第一次运行时创建的,并填充到重复使用的数组中。这意味着如果您创建两个组件,它们可能共享数组内对象的值。恕我直言,这是您想要避免的副作用,除非您明确地寻找该功能,即使您只使用该组件的一个实例。

B 的解决方案...

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

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

在这方面更安全,因为每次安装时它都会生成一个包含新对象的新数组。我的偏好是使用

created
,因为它将使数据在第一次绘制时可用,但由于变量预设为空数组,因此不会导致错误(就像模板中的错误,如果变量有
.length
未定义或为空)

这是一个说明差异的示例。并不是说当重新安装或重新创建组件时(此处没有区别)数据会丢失,但(顶部)两个组件不共享数据,而底部两个组件则共享数据。

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>


3
投票

您可以通过使用

[...Array(50)]
来实现此目的,它返回 50 个具有
undefined
值的项目,然后
map
该数组返回您的对象数组,这是在
mounted
生命周期挂钩中完成的:

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

2
投票

您可以在

<script>
标签内运行任何有效的 JavaScript 代码,因此这将起作用

<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 - 感谢您的澄清。支持 Boussadjra Brahim 的答案,哪个更好。


如果您希望每个组件都有独立的

boardfields
,请使用“工厂”功能来创建数据。

<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()
    };
  },
© www.soinside.com 2019 - 2024. All rights reserved.