Table

Reference

base"table"
String
Base name used to style component

caption-topfalse
Boolean
If true display caption on the top

definitionundefined
Array
Table definition is an optional array of objects that defines look and behavior of the table. See details below.

empty-filtered-text"No records for current filter"
String
Text displayed if the table is empty after filtering out all items

empty-text"Empty table"
String
Text displayed if the table is empty

filterempty string
StringRegExp
Use this string to filter items. Filtering always emits the update:page with value 1 and resets any active selection

items
(required)
undefined
Array
Data to display in the table. Each element of an array is an object. Single object is one record (row) of the data

items-per-page0
Number
Number of records (rows) on the single page. Setting it to the 0 disables pagination

locale"en-GB"
String
Locale used to compare and sort strings

mod-captionempty string
String
Style of the table caption

mod-cellempty string
String
Style of the single table cell

mod-header-cellempty string
String
Style of the single header cell element

mod-header-rowempty string
String
Style of the header row element

mod-rowempty string
String
Style of the table row element

mod-tableempty string
String
Style of the main table element

nameempty string
String
Name of the component

no-headerfalse
Boolean
If true does not display table headers

page1
Number
Current page number. Changing the page resets current selection

primary-key
(required)
undefined
String
This props should be the name of the property that is unique for every record. It is used as value for key attribute

selection-modeempty string
String
Enables or disables selection of the rows. Valid values are: 'single' (allows selection of single row only), 'multiple' (allows multiple rows to be selected) or empty string (disables selection). After new row is selected or unselected the input:selection event is emmited with an array of all selected records. Filtering, sorting, changing current page or modifying selection-mode prop resets current selection by emmiting an empty array

stateempty string
String
State of the table. Valid values are: 'busy' or empty string. Busy state disables pointer events on the table and renders contents of the busy slot instead of table rows

variantempty string
String
Active variant of the element mod-* props
Events
update:page
Emmited after filtering. Useful for updating pagination

update:filtered-count
Emmited after filtering. Useful for updating pagination

input:selection
Emmited after selecting rows. Event data contains an array of selected records
Slots
caption
Slot for the caption text. Position the caption using the caption-top prop

busy
Content of this slot replaces data records if the table is in the busy state

empty-table-message
Slot for the custom empty table message when the items prop is empty table

empty-filtered-table-message
Slot for the custom empty filtered table message when the table is empty after filtering

cell:[key]
Slot for the cells content. Useful for adding some html formatting, transforming value etc. Key is one of the keys of data record or additional key from the definition array. Slot props: value, item

colspan

Definition

Table definition is an optional array of objects that defines columns of the table. Each object represents one column, has one required, unique key property and number of options that define properties of the column. key can be the name of the property of the record or a different key that will add empty column. Content of these columns can be set in named slot or using definition function.

If definition is not provided component makes one using the first record of the data. All additional properties are set to default values. This may be enough for simple tables however to use features like sorting, filtering etc you need to provide definition array.

let definition: ref([
  {
    key: "id",
    visible: false,
  },
  {
    key: "first_name",
    sortable: true,
  },
  {
    key: "last_name",
    sortable: true,
  },
  {
    key: "email",
    sortable: true,
  },
  {
    key: "city",
    sortable: true,
  },
  {
    key: "country",
    sortable: true,
    class: (k, v) => (v == "ID" ? "bg-red-50" : ""),
  },
  {
    key: "edit",
  },
])

Each column is defined by object with following properties:

key
(required)
undefined
String
key is one of the properties of data from items prop or a new key. New keys apear as additional columns and their content can be set using slot or function f. This property is required.

labelundefined
String
Sets label for this column. If not present label is the same as key converted to Header Case

sortablefalse
Boolean
Enables sorting of the column. By default records are sorted as strings and using locale prop to compare values. Numbers and dates are sorted as numbers and dates. null, undefined and NaN values are always first when sorting in ascending direction

filterabletrue
Boolean
Enables filtering of the column. After filtering following actions happen: event update:filtered-count is emmited (event data contains number of elements after filtering), event update:page is emmited with value 1 (to reset pagination back to first page) and current selection is cleared by emmiting input:selection event with an empty array

visibletrue
Boolean
Toggles visiblity of the column

classundefined
Function
Function that should return string of classes to apply to each cell in column. Takes 3 arguments: key, value and item

fundefined
Function
If defined this function is called for every cell in this column and the return value is set as content of the cell. Takes 3 arguments: key, value and item. This function cannot be used to add html to cell content

filterByFunctiontrue
Boolean
If true filter content of column using value from function f

sortByFunctiontrue
Boolean
If true sort content of column using value returned from function f

Example - simple table

Id
First Name
Last Name
City
Department
Title
1AnthonyLinbohmMakuiBusiness DevelopmentQuality Engineer
2RichardMoultXihuLegalBudget/Accounting Analyst IV
3ChanceDallasMonctonSupportProduct Engineer
4RozamondAbbatucciChicoLegalSoftware Consultant
5AshelyPetrozziLafiaServicesStaff Accountant III
    <template>
  <v-table
    :items="example.data"
    :primary-key="example.primaryKey"
    class="w-full"
  ></v-table>
</template>
  
    <script setup>
import { reactive } from "vue";
import data from "../example-data/company-simple.json";

let example = reactive({
  data: data.slice(0, 5),
  primaryKey: "id",
});
</script>
  

Example - props and events

Example caption
Status
First Name
Last Name
Department
Title
City
Edit
PennieBysouth
Sales
Sales RepresentativeLopatyn
TabithaMcIlwain
Marketing
Accountant IChâtellerault
HailySpringford
Sales
Quality Control SpecialistShahrak
JorganGideon
Accounting
Environmental SpecialistKantyshevo
BevanSoeiro
Support
Human Resources ManagerBlagoveshchensk
5
empty string (normal state)
single
false
update:filtered-count 60
update:page 1
    <template>
  <v-table
    v-bind="example"
    v-model:page="page"
    @update:filtered-count="handleFilteredCount"
    @update:page="handlePageChange"
    @input:selection="handleSelection"
    class="min-w-full"
  >
    <template #cell:status="{ item }">
      <v-icon
        v-if="item.status"
        name="mdi-checkbox-outline"
        class="h-6 w-6 text-success-600 dark:text-success-400"
      ></v-icon>
      <v-icon
        v-else
        name="mdi-checkbox-blank-outline"
        class="h-6 w-6"
      ></v-icon>
    </template>

    <template #cell:department="{ item }">
      <div class="w-[150px] overflow-hidden text-ellipsis whitespace-nowrap">
        {{ item.department }}
      </div>
    </template>

    <template #cell:edit="{ item }">
      <!-- stop propagation to avoid selecting row -->
      <v-button
        mod-button="preset:plain"
        @click.stop="edit(item)"
        block
      >
        <v-icon
          name="mdi-account-edit"
          class="h-6 w-6"
        ></v-icon>
      </v-button>
    </template>

    <!-- <template #busy> -->
    <!--   <div class="my-5 flex justify-center"> -->
    <!--     <v-spinner -->
    <!--       type="svg" -->
    <!--       style-spinner="large" -->
    <!--     /> -->
    <!--   </div> -->
    <!-- </template> -->

    <template #caption>Example caption</template>
  </v-table>

  <!-- pagination and items per page -->

  <div class="my-5 justify-between lg:flex">
    <div>
      <v-pagination
        v-model="page"
        :items-count="example.itemsCount"
        :items-per-page="example.itemsPerPage"
        :max-pages="7"
      />
    </div>
    <div class="mt-4 lg:mt-0">
      <label
        for="items-per-page"
        class="mr-4"
      >
        Items per page
      </label>
      <v-select
        v-model.number="example.itemsPerPage"
        id="items-per-page"
        :items="[0, 5, 10, 20, 50]"
      ></v-select>
    </div>
  </div>

  <!-- edit modal -->

  <v-modal
    v-model="editModalIsVisible"
    title="Edit"
    primaryButtonClose
    secondaryButtonClose
  >
    <pre
      v-html="editModalContent"
      class="my-0 ml-4 whitespace-pre"
    ></pre>
  </v-modal>

</template>
  
    <script setup>
import { ref, reactive } from "vue";
import data from "../example-data/company-complete.json";

let definition = [
  {
    key: "id",
    visible: false,
  },
  {
    key: "status",
    sortable: true,
  },
  {
    key: "first_name",
    sortable: true,
  },
  {
    key: "last_name",
    sortable: true,
  },
  {
    key: "department",
    sortable: true,
  },
  {
    key: "title",
    sortable: true,
  },
  {
    key: "city",
    sortable: true,
  },
  {
    key: "edit",
  },
];

let example = reactive({
  items: data.slice(0, 60),
  itemsPerPage: 5,
  primaryKey: "id",
  filter: "",
  busy: false,
  selectionMode: "single",
  captionTop: false,
  locale: "en-GB",
  state: "",
  definition: definition,
});

let page = ref(1);
let editModalIsVisible = ref(false);
let editModalContent = ref("");

let edit = (content) => {
  editModalContent.value = JSON.stringify(content, null, 2);
  editModalIsVisible.value = true;
};

let events = ref([]);

let handleFilteredCount = (count) => {
  example.itemsCount = count;
  events.value.unshift({ ev: "update:filtered-count", data: count });
};

let handleSelection = (selection) => {
  events.value.unshift({ ev: "input:selection", data: selection });
};

let handlePageChange = (page) => {
  events.value.unshift({ ev: "update:page", data: page });
};
</script>
  

Example - colspan item property

Item can have special property colspan: {}. Properties of this object are rendered as full row below item. To render them use colspan slot.

Id
First Name
Last Name
City
Department
Title
1AnthonyLinbohmMakuiBusiness DevelopmentQuality Engineer
First name: Anthony
City: Makui
2RichardMoultXihuLegalBudget/Accounting Analyst IV
First name: Richard
City: Xihu
3ChanceDallasMonctonSupportProduct Engineer
First name: Chance
City: Moncton
4RozamondAbbatucciChicoLegalSoftware Consultant
First name: Rozamond
City: Chico
5AshelyPetrozziLafiaServicesStaff Accountant III
First name: Ashely
City: Lafia
    <template>
  <v-table
    :items="example.data"
    :primary-key="example.primaryKey"
    class="w-full"
  >
    <template #colspan="{ item }">
      <div class="bg-secondary-200 dark:bg-dark-700 p-2 px-4 m-2">
        <div>
          <span class="font-semibold">First name:</span>
          {{ item["first_name"] }}
        </div>
        <div>
          <span class="font-semibold">City:</span>
          {{ item["city"] }}
        </div>
      </div>
    </template>
  </v-table>
</template>
  
    <script setup>
import { reactive } from "vue";
import data from "../example-data/company-simple.json";

let example = reactive({
  data: data.slice(0, 5),
  primaryKey: "id",
});

example.data = example.data.map((i) => {
  return { colspan: { ...i }, ...i };
});
</script>