Search code examples
vue.jsdatatableheadervuetify.jsslot

Slot headers vuetify 2.0


Good morning, I am modifying the slot header of a data table in vuetify.js to add a tooltip, all this does it well, but the arrows of asc and desc are not shown, I would like to know what I am doing wrong.

<template  v-slot:header="{ props: { headers } }">
    <thead>
        <tr>
            <th 
                style="white-space: nowrap"
                :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
                @click="changeSort(header.value)"
                v-for="element in headers" 
                :key="element.text">
                <v-tooltip top>
                    <template v-slot:activator="{ on }">
                        <span v-on="on">{{element.text}}</span>
                    </template>
                    <span>{{element.text}}</span>
                </v-tooltip>
            </th>
        </tr>
    </thead>
</template>

Solution

  • As noted in the documentation,

    It is important to note some slot (eg: item/body/header) will completely takes over the internal rendering of the component which will require you to re-implement functionalities such as selection and expansion.

    But you can customize the default header

    You can use the dynamic slots header. to customize only certain columns. is the name of the value property in the corresponding header item sent to headers.

    Modifying the codepen in that second section of the documentation, you can see how you can add tooltips for each header, using dynamic slot names. Here I have a tooltip for the first 3 columns, and just the default text for the remaining columns, but populating a tooltip text for all in headerTooltips will produce tooltips for all headers.

    <div id="app">
      <v-app id="inspire">
        <v-data-table
          :headers="headers"
          :items="desserts"
          class="elevation-1"
        >
          <template v-for="header in headers" v-slot:[`header.${header.value}`]="{ header }">
            <v-tooltip v-if="headerTooltips[header.value]" bottom :key="header.value">
              <template v-slot:activator="{ on }">
                <span v-on="on">{{ header.text }}</span>
              </template>
              <span>{{ headerTooltips[header.value] }}</span>
            </v-tooltip>
            <span v-else>{{ header.text }}<span>
          </template>
        </v-data-table>
      </v-app>
    </div>
    
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      data: () => ({
        headers: [
          {
            text: 'Dessert (100g serving)',
            align: 'start',
            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' },
        ],
        headerTooltips: {
          name: 'Name tooltip',
          calories: 'Calories tooltip',
          fat: 'Fat tooltip'
        },
        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%',
          },
          {
            name: 'Cupcake',
            calories: 305,
            fat: 3.7,
            carbs: 67,
            protein: 4.3,
            iron: '8%',
          },
          {
            name: 'Gingerbread',
            calories: 356,
            fat: 16.0,
            carbs: 49,
            protein: 3.9,
            iron: '16%',
          },
          {
            name: 'Jelly bean',
            calories: 375,
            fat: 0.0,
            carbs: 94,
            protein: 0.0,
            iron: '0%',
          },
          {
            name: 'Lollipop',
            calories: 392,
            fat: 0.2,
            carbs: 98,
            protein: 0,
            iron: '2%',
          },
          {
            name: 'Honeycomb',
            calories: 408,
            fat: 3.2,
            carbs: 87,
            protein: 6.5,
            iron: '45%',
          },
          {
            name: 'Donut',
            calories: 452,
            fat: 25.0,
            carbs: 51,
            protein: 4.9,
            iron: '22%',
          },
          {
            name: 'KitKat',
            calories: 518,
            fat: 26.0,
            carbs: 65,
            protein: 7,
            iron: '6%',
          },
        ],
      }),
    })
    

    Here is that Codepen: https://codepen.io/keeganwitt/pen/ExVVyqa