【问题标题】:Make a table layout with CSS grid with nested vue v-for loops使用带有嵌套 vue v-for 循环的 CSS 网格制作表格布局
【发布时间】:2021-12-09 08:47:35
【问题描述】:

我已经嵌套了想要以表格格式显示的数据。这是一些示例数据;在实际应用中,rows 中有时可能会有几十个条目。

<script>
export default {
  name: 'Example',

  data () {
    return {
      results: [
        { a: 'AAA', rows: { BBB: 'CCC' } },
        { a: 'D', rows: { E: 'F', G: 'H' } },
        { a: 'Tom, Dick & Harry', rows: { x: 'y' } },
      ],
    }
  },
}
</script>

注意:内部值('CCC'、'F'、'H'、'y')可能最终会成为进一步嵌套的数组或对象。

我尝试了这种网格布局,带有v-for 循环:

<template>
<div style="width:100%">
  <div v-for="(res,key) in results" :key="key" class="results">
    <div class="A">{{res.a}}</div>
    <div v-for="(c,b) in res.rows" :key="b">
      <div class="B">{{b}}</div>
      <div class="C">{{c}}</div>
    </div>
  </div>
</div>
</template>
<style scoped>
.results {display:grid;grid-template-columns: 1fr 1fr;}
.A {font-weight:bold;grid-column:1/3;}
.B {grid-column:1;padding:0.5rem;}
.C {grid-column:2;padding:0.5rem;}
</style>

(顺便说一句:更合乎逻辑的grid-column:1/2,要获得两列的跨度,似乎什么都不做......)

这给了我错误的布局;我已经附加了一个很好的老式表格布局来展示我想要实现的目标(问题结束时的 HTML)。

我有一个简单的错误吗?或者,有没有更好的方法来同时使用 vue 和 grid? (请记住,如上所述,我最终可能会使用第三个 v-for 循环。)

顺便说一句,上次我尝试使用网格我放弃了,并使用了&lt;table&gt;标签;我通过将&lt;tbody&gt; 放在&lt;tbody&gt; 上来解决v-for 创建html 标签的问题,即每个部分都有一个表格正文。但这不会扩展到第三个 v-for 循环。如果可以的话,我宁愿使用 CSS 网格,因为它为响应式布局提供了更多功能。

表格HTML,供参考:


  <table border="1" cellspacing=0 style="width:100%;">
    <tr>
      <td colspan="2"><b>AAA</b></td>
    </tr>
    <tr>
      <td>BBB</td>
      <td>CCC</td>
    </tr>
    <tr>
      <td colspan="2"><b>D</b></td>
    </tr>
    <tr>
      <td>E</td>
      <td>F</td>
    </tr>
    <tr>
      <td>G</td>
      <td>H</td>
    </tr>
    <tr>
      <td colspan="2"><b>Tom, Dick & Harry</b></td>
    </tr>
    <tr>
      <td>x</td>
      <td>y</td>
    </tr>
  </table>

【问题讨论】:

    标签: vue.js css-grid


    【解决方案1】:

    尝试使用数组而不是对象:

    new Vue({
      el: '#demo',
      data () {
        return {
          results: [
            { a: 'AAA', rows: [{id:'BBB'}, {id:'CCC', more: [{id: '1'}, {id: '2'}]}] },
            { a: 'D', rows: [{id:'E'}, {id:'F', more: [{id: '1'}, {id: '2'}]}, {id:'G'}, {id:'H', more: [{id: '1'}, {id: '2'}]}] },
            { a: 'Tom, Dick & Harry', rows: [{id:'x'}, {id:'y', more: [{id: '1'}, {id: '2'}]}] },
          ],
        }
      },
    })
    
    
    Vue.config.productionTip = false
    Vue.config.devtools = false
    .results {display:grid;grid-template-columns: 1fr 1fr;}
    .A {font-weight:bold;grid-column:1/3;}
    .B {grid-column:1;padding:0.5rem;}
    .C {grid-column:2;padding:0.5rem;}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="demo">
    
    <div style="width:100%">
      <div v-for="(res,key) in results" :key="key" class="results">
        <div class="A">{{res.a}}</div>
        <div v-for="(c,b) in res.rows" :key="b">
          <div class="B">{{c.id}}</div>
          <div v-for="(z,i) in c.more" :key="i">
            <div class="C">{{z.id}}</div>
          </div>
        </div>
      </div>
    </div>
          
    </div>

    【讨论】:

    • 有趣。这看起来不像是扩展到第三个嵌套循环(除非您建议将所有嵌套对象展开到单个数组中?)。但我更感兴趣的是 why 使用数组水平发送单元格,而使用对象垂直发送单元格。你能解释一下吗?
    • 嘿伙计,如果你想要更多的嵌套循环,只需添加更多 v-for 循环。在您的示例中,您在嵌套的 v-for 中有 2 个 div,但在 b:c and x:y 的情况下只有一个对象。
    • 我用更多嵌套对象更新了答案(如果这是你想要完成的),请看一下,干杯:)
    【解决方案2】:

    我只是stumbled upon the solution 讨论了如何处理 vue v-for 循环,当您不希望它们创建 DOM 元素时,这正是我需要的。

    首先解释问题,以及为什么我的布局错误:applying the layout to the grid container's child elements 上的 CSS 网格 坚持。 (据我所知,它在这方面完全不灵活,例如,无法将 div 标记为不属于布局的一部分。)

    无论如何,解决方案是将我的内部&lt;div v-for=""&gt; 转换为&lt;template v-for=""&gt;

    <template>
    <div style="width:100%">
      <div v-for="(res,key) in results" :key="key" class="results">
        <div class="A">{{res.a}}</div>
        <template v-for="(c,b) in res.rows">
          <div class="B" :key="b">{{b}}</div>
          <div class="C" :key="'_'+b">{{c}}</div>
        </template>
      </div>
    </div>
    </template>
    

    有一个缺点:您不能将:key 放在&lt;template&gt; 标记上。很公平,因为它没有被渲染。但这意味着&lt;template&gt;每个 子元素都需要:key,并且它们必须各不相同。我在上面使用了一种 hacky 的解决方法。 (另见https://stackoverflow.com/a/67784407/841830

    在我的实际应用中,我已经放弃了这两个:key 定义,并使用&lt;!-- eslint-disable vue/require-v-for-key --&gt; 来阻止eslint 抱怨。它是my understanding,这不会造成任何问题,因为如果它发生变化,整个res 将被替换。但如果不确定,请在任何地方使用:key

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-09
      • 2020-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-20
      • 2014-09-01
      • 2020-11-10
      相关资源
      最近更新 更多