Vue - 使用 v-for 两次呈现表格行和单元格?

Posted

技术标签:

【中文标题】Vue - 使用 v-for 两次呈现表格行和单元格?【英文标题】:Vue - Using v-for twice to render a tables rows and cells? 【发布时间】:2017-04-30 10:05:27 【问题描述】:

我想使用 Vue 来呈现一个包含行的表格,但将单元格作为一个组件。

我已经将a working example 作为我希望看到的最终结果,并有一些与我认为我可以如何去做的代码有关:

HTML

<div id="app">
  <table>
    <thead>
      <tr>
        <th>Row</th>
        <th>ID</th>
        <th>Name</th>
        <th>Age</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, rindex) in people">
        <td> rindex </td>
        <cell v-for="(value, vindex, rindex) in row" :value="value" :vindex="vindex" :rindex="rindex"></cell>
      </tr>
    </tbody>
  </table>
  <template id="template-cell">
    <td> value </td>
  </template>
</div>

JS

// Register component
Vue.component('cell', 
  template: '#template-cell',
  name: 'row-value',
  props: ['value', 'vindex', 'rindex']
  // In here I would like to access value, vindex and rindex
);
// Start application
new Vue(
  el: '#app',
  data: 
    people: [
      id: 3, name: 'Bob', age: 27,
      id: 4, name: 'Frank', age: 32,
      id: 5, name: 'Joe', age: 38
    ]
  
);

这是因为,在 Vue documentation on v-for 他们展示了这个例子:

And another for the index:

<div v-for="(value, key, index) in object">
   index .  key  :  value 
</div>

从逻辑上思考,我应该能够在没有太多问题的情况下获取单元格组件中的行索引,但是 this is not so 因为它出现了一堆错误,表明这些值是未定义的。

如果有人能在这里指出我正确的方向,那么我将不胜感激,因为我对这个问题一无所知,但真的很想了解如何正确实施。

(注意:我想在组件中渲染单元格的原因是为了注册值的变化,see the answer 到另一个问题,如果你有兴趣我在这里问)

【问题讨论】:

【参考方案1】:

您只需将cell 组件包含在template 元素中,这是因为html 中的表格需要only td inside tr,当它看到cell 时,它不会呈现它(参见Angular @ 的类似问题987654322@)。但是模板可以在这里用作内容片段,并且在 vue 编译后,它将添加tr 来代替 HTML 中的单元格。

  <tr v-for="(row, rindex) in people">
    <td> rindex </td>
    <template>
       <cell  v-for="(value, vindex) in row" :value="value" :vindex="vindex" :rindex="rindex" ></cell>
    </template>
  </tr>

见工作笔here。

【讨论】:

感谢 codepen 示例。我不确定 rindex 这样的自定义标签是否可以用作 v-for 中的迭代器,并最终写出完全不同的答案。 当我尝试这样做时,我发现了类似的东西,但它在模板标签中使用了 v-for。我认为将其排除在我的问题之外是一种技巧,但是当您说出您所拥有的并现在考虑它时,这是处理此问题的合乎逻辑的方法,并且在处理 tr 和 td 标签时有点奇怪您不能将它们包装在任何其他标签中,否则表格将无法正确呈现。【参考方案2】:

我不确定您是否可以在v-for 构造函数中将index 替换为rindex。如果v-for 的实现需要keyindex 的字符串标签,那么您的rindexvindex 将不起作用。

我看到另一个问题,引用自相关参考页面:List Rendering in Vue

迭代对象时,顺序基于 Object.keys() 的键枚举顺序,不保证跨 javascript 引擎实现一致。

因此,您的第一个单元格可能具有 (id, key, name) 的顺序,而您的第二个单元格可能具有 (name, id, key) - 不同的顺序。因此,最好的方法是为cell避免对象迭代器,并明确定义出现的顺序如下:

<tr v-for="(person, index) in people">
    <td> index </td>
    <cell :value="index" valueType="index" :rowIndex="index"></cell>
    <cell :value="person.id" valueType="id" :rowIndex="index"></cell>
    <cell :value="person.name" valueType="name" :rowIndex="index"></cell>
</tr>

现在你的单元格组件定义需要修改为:

Vue.component("cell", 
    template: "#template-cell",
    name: "row-value",
    props: ["value", "valueType", "rowIndex"],
    // your component code here...
)

现在您可以在单元格组件中使用valueTyperowIndex

【讨论】:

我在阅读文档时确实注意到了该注释,并且过去让我感到困惑,所以您所说的对我来说确实有意义,谢谢。两个问题,一个是不应该有一个道具"value",而且,这是一个菜鸟问题,但我的意思是从逻辑上思考,如果我在每个单元格上创建一个侦听器,它将比每行创建一个侦听器占用更多的资源或确实没有区别吗? 抱歉,props 中也应该有一个 value 字段。我忘记了。我将更新答案以在道具中包含价值。对于关于性能/资源消耗的第二个问题,是的 - 您将在浏览器上消耗更多内存。我认为这并没有太大的区别,因为 Vue 很好地处理了资源,从而使我们能够创建一个易于维护的应用程序。看看这个:stefankrause.net/wp/?p=316

以上是关于Vue - 使用 v-for 两次呈现表格行和单元格?的主要内容,如果未能解决你的问题,请参考以下文章

Vue - ElementUI中循环渲染表格,控制字段的显示与隐藏 v-if与v-for同时使用

对表格进行排序时,Vue v-for循环中的重复键

iOS - drawRect:调用了两次

整行和单元格的 Google 表格条件格式

Vue 2 图像无法在某些浏览器中呈现

vue v-for输出表格结构