【问题标题】:V-data-table controlling expanded items via v-slot:body通过 v-slot:body 控制扩展项目的 V-data-table
【发布时间】:2020-03-02 13:16:37
【问题描述】:

vuetify 2.0 v-data-tables 的文档没有指定如何通过 v-slot:body 控制展开的项目。我有一张表,我需要用 body v-slot 指定,并想使用扩展功能。

预期行为是通过单击表格中某一列中的按钮,该行会在下方展开。

我正在使用 v-slot:body,因为我需要完全自定义列内容。我正在从 vuetify 1.5 迁移代码,其中 props.expanded 启用了此功能。

Codepen:https://codepen.io/thokkane/pen/PooemJP

<template>
  <v-data-table
    :headers="headers"
    :items="deserts"
    :expanded.sync="expanded"
    :single-expand="singleExpand"
    item-key="name"
    hide-default-footer
  >
    <template v-slot:body="{ items }">
      <tbody>
        <tr v-for="item in items" :key="item.name">
          <td>
            <v-btn @click="expanded.includes(item.name) ? expanded = [] : expanded.push(item.name)">Expand</v-btn>
          </td>
        </tr>
      </tbody>
    </template>
    <template v-slot:expanded-item="{ headers, item }">
      <span>item.name</span>
    </template>
  </v-data-table>
</template>

<script>
  export default {
    data () {
      return {
        expanded: [],
        singleExpand: false,
        headers: [
          { text: 'Dessert (100g serving)', align: 'left', sortable: false, value: 'name' },
          { text: 'Calories', value: 'calories' },
          { text: 'Fat (g)', value: 'fat' },
          { text: 'Carbs (g)', value: 'carbs' },
          { text: 'Protein (g)', value: 'protein' },
          { text: 'Iron (%)', value: 'iron' },
          { text: '', value: 'data-table-expand' },
        ],
        desserts: [
          {
            name: 'Frozen Yogurt',
            calories: 159,
            fat: 6.0,
            carbs: 24,
            protein: 4.0,
            iron: '1%',
          },
          {
            name: 'Ice cream sandwich',
            calories: 237,
            fat: 9.0,
            carbs: 37,
            protein: 4.3,
            iron: '1%',
          },
          {
            name: 'Eclair',
            calories: 262,
            fat: 16.0,
            carbs: 23,
            protein: 6.0,
            iron: '7%',
          },
        ],
      }
    },
  }
</script>

【问题讨论】:

    标签: vuetify.js


    【解决方案1】:

    当您将v-slot:bodyv-slot:expanded-item 一起使用时,您将覆盖v-slot:expanded-item 中的更改。这是因为expanded-item 插槽位于body 插槽内。如果您打算使用body 进行自定义,很遗憾您必须自定义里面的所有内容。

    想象一下这样的结构:

    <div slot="body">
      <div slot="item">...</div>
      <div slot="expanded-item">...</div>
      etc...
    <div>
    

    所以在这种情况下&lt;template v-slot:body&gt; 将替换&lt;div slot="body"&gt; 和里面的任何东西。因此&lt;template v-slot:expanded-item&gt; 的使用不适用于&lt;template v-slot:body&gt;。此外,v-slot:body 道具不包括特定于项目的属性和事件,如 select(), isSelected, expand(), isExpanded 等。

    我建议您改用v-slot:item。您可以完成同样的事情,而无需使用更少的代码自定义所有内容。

    这样的事情应该可以工作:

    <template v-slot:item="{ item, expand, isExpanded }">
      <tr>
        <td>
          <v-btn @click="expand(!isExpanded)">Expand</v-btn>
        </td>
        <td class="d-block d-sm-table-cell" v-for="field in Object.keys(item)">
          {{item[field]}}
        </td>
      </tr>
    </template>
    
    <template v-slot:expanded-item="{ headers, item }">
      <td :colspan="headers.length">Expanded Content</td>
    </template>
    

    如果您想访问 JavaScript 中的扩展项目,请不要忘记将 :expanded.sync="expanded" 添加到 &lt;v-data-table&gt; 。要在点击时打开唯一项目,您需要在 &lt;v-data-table&gt; 上设置 item-key="" 属性。

    【讨论】:

    • 谢谢。在这里修改它codepen.io/thokkane/pen/PooemJP。如何将扩展限制为仅单击的项目?现在它打开了表中的所有项目。
    • 我认为您需要将item-key="name" 属性设置为&lt;v-data-table&gt;
    【解决方案2】:

    对于较新的版本,您也可以使用 body slot 来实现这一点,这是我的代码

    https://codepen.io/saurabhtalreja/pen/JjyWxEr

    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      data: () => ({
        headers: [{
            name: 'id',
            text: 'id',
            value: 'id'
          },
          {
            name: 'text',
            text: 'text',
            value: 'text'
          }
        ],
        items: [{
            id: 1,
            text: "Item 1"
          },
          {
            id: 2,
            text: "Item 2"
          },
          {
            id: 3,
            text: "Item 3"
          },
          {
            id: 4,
            text: "Item 4"
          },
          {
            id: 5,
            text: "Item 5"
          }
        ]
      })
    })
    <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"/>
    <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>
    
    <div id="app">
      <v-app>
        <v-content>
          <v-container grid-list-xl>
            <v-data-table class="elevation-1" :headers="headers" :items="items" show-expand hide-default-footer>
    
              <template v-slot:body="{ items, headers, expand, isExpanded }">
                <tbody>
                  <tr v-for="item in items" :key="item.name">
                    <td>
                      <v-btn @click="expand(item,!isExpanded(item))">Expand</v-btn>
                      <div v-if="isExpanded(item)" :style="{width:  '250px'}">
                        Expanded content for {{ item.text }}
                      </div>
                    </td>
                    <td>{{item.id}}</td>
                    <td>{{item.text}}</td>
    
                  </tr>
                </tbody>
              </template>
    
            </v-data-table>
          </v-container>
        </v-content>
      </v-app>
    </div>
    <div id="app">
      <v-app>
        <v-content>
          <v-container grid-list-xl>
            <v-data-table class="elevation-1" :headers="headers" :items="items" show-expand hide-default-footer>
              <template v-slot:expanded-item="{item, headers}">
                <td :colspan="headers.length">
                  expanded content for {{ item.text }}
                </td>
              </template>
    
            </v-data-table>
          </v-container>
        </v-content>
      </v-app>
    </div>

    【讨论】:

      猜你喜欢
      • 2020-01-25
      • 1970-01-01
      • 1970-01-01
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2018-12-08
      • 2021-02-09
      相关资源
      最近更新 更多