使用自定义表格体实现选择Vuetify数据表的所有行

15

我不知道如何在我使用自定义实现的插槽body时,为我的data-table使用Vuetify v2实现“全选”选项。

这里是一个小例子:

<template>
  <v-card
    max-width="300"
    class="pa-6"
  >
    <v-data-table
      :items="tasks"
      :headers="headers"
      show-select
      dense
    >
      <template v-slot:body="{ items }">
        <tbody>
          <tr
            v-for="item in items"
            :key="item.id"
          >
            <td>
              <v-checkbox
                v-model="selectedTasks"
                :value="item.id"
                style="margin:0px;padding:0px"
                hide-details
              />
            </td>
            <td>{{ item.text }}</td>
            <td>
              <v-btn
                text
                icon
                x-small
              >
                <v-icon>pageview</v-icon>
              </v-btn>
            </td>
          </tr>
        </tbody>
      </template>
    </v-data-table>
  </v-card>
</template>

<script>
export default {
  data() {
    return {
      headers: [
        { text: 'task', value: 'text' },
        { text: 'actions' }
      ],
      selectedTasks: []
    }
  },
  computed: {
    tasks() {
      return [
        { id: 1, text: 'Collect packets' },
        { id: 2, text: 'Buy bread' }
      ]
    }
  }
}
</script>

这将生成以下数据表:

enter image description here

现在我想实现这样一个功能:当选择“全部”复选框(如上图所示)时,它会选择表格中的所有行。
文档中提到要实现插槽header.data-table-select来自定义全选按钮,并且我可以在数据表的slots示例中找到下面的示例。
<template v-slot:header.data-table-select="{ on , props }">
    <v-simple-checkbox
       color="purple"
       v-bind="props"
       v-on="on"
    />
</template>

然而,当我勾选此框时,无法选择所有行。我没有找到任何示例来实现使用“自定义”表格正文的全选功能。希望有人能在这里帮助我。 提前致谢。

1个回答

24

数据表格的 v-model 必须设置为 selectedItems,而选择复选框需要具有项目集合的值。

<!DOCTYPE html>
<html>

<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@3.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>

<body>
<div id="app">
    <v-app>
        <v-content>
            <v-container>
                <h2>Data Table</h2>

                <v-data-table v-model="selectedTasks" :headers="headers" :items="tasks" item-key="id" show-select>

                    <template v-slot:body="{ items }">
                        <tbody>
                            <tr v-for="item in items" :key="item.id">
                                <td>
                                    <v-checkbox v-model="selectedTasks" :value="item" style="margin:0px;padding:0px"
                                        hide-details />
                                </td>
                                <td>{{ item.text }}</td>
                                <td>
                                    <v-btn text icon x-small>
                                        Edit
                                    </v-btn>
                                </td>
                            </tr>
                        </tbody>
                    </template>
                </v-data-table>
                <v-btn v-on:click="addTask()">Add Task</v-btn>
            </v-container>
        </v-content>
    </v-app>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<script>
    new Vue({
        el: '#app',
        vuetify: new Vuetify(),

        data() {
            return {
                headers: [
                    {
                        text: 'Task',
                        value: 'text'
                    },
                    {
                        text: 'Actions'
                    }
                ],
                tasks: [
                    {
                        id: 1,
                        text: 'Collect packets'
                    },
                    {
                        id: 2,
                        text: 'Buy bread'
                    }
                ],
                selectedTasks: []
            }
        },
        methods: {
            addTask() {
                this.tasks = this.tasks.map(t => ({...t}))
                this.tasks.push({id: this.tasks.length + 1, text: 'New Task'});

                this.selectedTasks = this.selectedTasks.map(t => {
                    return this.tasks.find(e => e.id == t.id) || t;
                })
            }
        }
    })
</script>
</body>

</html>


非常感谢。我一直在寻找这个解决方案,终于找到了。 - Saroj
嗨,我刚刚检查过了,它可以与分页一起使用,你能提供更多关于你如何测试的信息吗? - Edin Omeragic
1
当API调用后项目发生更改时,复选框会自动选中。 - S. Farooq
只需使用模型ID重新同步selectedTasks。 - Edin Omeragic
@EdinOmeragic,您能详细说明如何进行重新同步吗?您的示例对我有效,但在API调用后,我仍然遇到了所有复选框都被选中的问题。 - lrossy
我已经更新了示例,请注意,在更新任务后,selectedTasks 也会被更新,以包含与 id 匹配的 tasks 集合中的对象实例。 - Edin Omeragic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接