Таблица Vue в одном цикле html

У меня есть массив с размерами обуви и количеством каждой из них в магазине, структура такая:

array = {
    36=>1,   
    37=>0,
    38=>5,
    39=>2
}

В моей таблице ключи в этой таблице (здесь 36, 37 ...) - TH, а значение - TD. Я не могу сделать это за один цикл. Я пробовал вот так:

<table class="table">
    <tr>
        <th v-for="(quantity, key) in productSizes" :key='key'>{{key}}</th>
    </tr>

    <tr>
    <td>Here should be quantity for each size<td>
    </tr>

</table>

Есть возможность сделать это сразу?

Вот структура, как она должна выглядеть (есть ввод, потому что кто-то может изменить количество).

введите описание изображения здесь


person wenus    schedule 06.09.2017    source источник


Ответы (2)


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

console.clear()

const shoeSizes = {
  36: 0,
  37: 2,
  38: 1,
  39: 3,
  40: 2,
  41: 0
}

new Vue({
  el: "#app",
  data:{
    shoeSizes
  }
})
<script src="https://unpkg.com/[email protected]"></script>
<div id="app">
  <table>
    <tr>
      <th v-for="quantity, key in shoeSizes">{{key}}</th>
    </tr>
    <tr>
      <td v-for="quantity, key in shoeSizes">
        <input type="text" v-model="shoeSizes[key]">
      </td>
    </tr>
  </table>
</div>

Если предположить, что существует даже 100 размеров обуви, влияние на производительность будет незначительным.

Изменить

Что ж, я могу придумать, как вы могли бы отрендерить это за один цикл. Использование функции рендеринга.

console.clear()

const shoeSizes = {
  36: 0,
  37: 2,
  38: 1,
  39: 3,
  40: 2,
  41: 0
}

new Vue({
  el: "#app",
  data:{
    shoeSizes
  },
  render(h){
    let headers = [], cells = []
    // build the headers and cells
    for (let key of Object.keys(this.shoeSizes)){
      // header is easy
      headers.push(h('th', key))
      
      // build props for the input to implement v-model
      let vmodel = {
        domProps: {
          value: this.shoeSizes[key]
        },
        on: {
          input: event => {
            this.$set(this.shoeSizes, key, event.target.value) 
            this.$emit('input', event.target.value)
          }
        }
      }
      // add the vell
      cells.push(h('td', [h('input', vmodel)]))      
    }
    // render the table with headers and cells in the 
    // right places
    return h('table', [h('tr', headers), h('tr', cells)])
  }
})
<script src="https://unpkg.com/[email protected]"></script>
<div id="app"></div>

Эта функция рендеринга строит заголовки и ячейки в одном цикле, а затем рендерит таблицу вокруг них. Но я думаю, вы согласитесь, что это излишне сложно.

person Bert    schedule 06.09.2017

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

Подобный пример можно найти здесь

<tbody>
<template v-for="(quantity, key) in productSizes" :key='key'>
    <tr>
        <th>{{key}}</th>
    </tr>
    <tr>
        <td>{{key}}<td>
    </tr>
</template>
</tbody>

Изменить

Заставил его работать с одним циклом v-for, используя приведенный выше пример (на этот раз было время протестировать).

const productSizes = {
  36: 0,
  37: 2,
  38: 1,
  39: 3,
  40: 2,
  41: 0
}

new Vue({
  el: "#app",
  data:{
    productSizes
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <table>
    <tbody>
      <template v-for="(quantity, key) in productSizes">
          <tr>
              <th>{{key}}</th>
          </tr>
          <tr>
          <td><input v-model="productSizes[key]" type="text"><td>
          </tr>
      </template>
    </tbody>
  </table>
</div>

person coolspeedway    schedule 06.09.2017
comment
После вашего редактирования он по-прежнему не работает так, как сформулировал вопрос. В вашем примере размеры расположены вертикально, а вопрос требует, чтобы они были расположены горизонтально. - person Bert; 07.09.2017