Vue.js循环模板

时间:2019-04-30 07:51:21

标签: vue.js

我有很多项目,并且有很多用户。 我想用:

Project  | User | ....
         | U1   | ....
A        | U2   | ....    
         | U3   | .... 
----------------------
         | U1   | ....
B        | U2   | ....    
         | U3   | .... 

所以我使用一个像这样的表元素:

<table>
  <tr>
    <th>Poject</th>
    <th>User</th>
    <th v-for="..." :key="...">....</th>
  </tr>
  <template v-for="p in projects"> // problem :key
    <tr v-for="(u, i) in users" :key="u">
      <td v-if="i===0" :rowspan="users.length">{{p.name}}</td>
      <td>{{u.name}}</td>
      <td v-for="..." :key="...">...</td>
    </tr>
  </template>
</table>

我知道我们不能在模板中循环,因为它不是元素,并且我需要将键放在内部的元素中。 一个想法是用新的对象数组创建一个计算对象,该对象数组可以像这样反映我的Vue的结构:

[
 { project : "A",
   users : ["U1", "U2", "U3"]
 },
 { project : "B",
   users : ["U1", "U2", "U3"]
 },
]

之后,我只需要在这个新结构中循环。 但是,如果我有很多数据,我会浪费时间来重新创建此结构。

您有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

我添加了两种方法来执行此操作。使用css grid的人,因为这样做似乎是更好的解决方案,但是也许您想使用table标记,因为有些工作对此进行了解析。 (例如,我知道复制粘贴到excel可以用于表格)

查看此沙箱:

https://codesandbox.io/s/ll3pml3kjl?fontsize=14

App.vue

<template>
  <div id="app">
    <table border="1">
      <tr>
        <th>Project</th>
        <th>Users</th>
      </tr>
      <project-row
        v-for="(user, index) in allUsers"
        :user="user"
        :index="index"
        :key="user.name" />
    </table>

    <div class="grid-table">
      <strong class="project">Project</strong>
      <strong class="user">User</strong>
      <template class="projects" v-for="project in projects">
        <span class="project">{{ project.name }}</span>
        <span class="user" v-for="user in project.users">{{ user }}</span>
      </template>
    </div>

  </div>
</template>

<script>
import ProjectRow from "./components/ProjectRow";

export default {
  name: "App",
  components: {
    ProjectRow
  },
  computed: {
    allUsers() {
      return this.projects.map(p => {
        return p.users.map((u, i) => {
          return {
            first_in_project_group: i === 0,
            name: u,
            project: p.name,
            total_users: p.users.length
          }
        });
      }).flat();
    }
  },
  data() {
    return {
      projects: [
        {
          name: "A",
          users: ["UA1","UA2","UA3"]
        },
        {
          name: "B",
          users: ["UB1","UB2","UB3"]
        }
      ]
    }
  }
};
</script>

<style lang="scss">
.grid-table {
  display: grid;
  grid-template-columns: auto 1fr;
  max-width: 50vw;
  border: 1px solid #000;
  grid-gap: 10px;
  padding: 10px;
  justify-self: center; 

  .project {
    grid-column: 1;
    font-weight: bold;
  }

  .user {
    grid-column: 2;
    font-weight: bold;
  }
}
</style>

ProjectRow.vue

<template>
  <tr>
    <td v-if="user.first_in_project_group" :rowspan="user.total_users">{{ user.project }}</td>
    <td>{{ user.name }}</td>
  </tr>
</template>

<script>
  export default {
    props: {
      'index': true,
      'user': {
        default() {
          return {
            name: '',
            project: '',
            total_users: 0
          }
        }
      }
    },
    computed: {
      users() {
        return this.project.users;
      }
    }
  }
</script>