Table
Demos
Content density
Available density variants for the ui
prop: compact
/ loose
.
Density
Size
ID | Name | Bid | Last updated | Operations |
---|---|---|---|---|
3154 | Steve Rogers | ¥1024.00 | 2013-11-17 | |
3155 | Thor Odinson | ¥598.00 | 2014-02-14 | |
3156 | Tony Stark | ¥820.00 | 2017-06-10 | |
3157 | Stephen Strange | ¥736.00 | 2018-01-09 |
<template>
<article>
<section>
<h4>Density</h4>
<veui-radio-group
v-model="density"
:items="[
{ label: 'Compact', value: 'compact' },
{ label: 'Normal', value: 'normal' },
{ label: 'Loose', value: 'loose' }
]"
/>
</section>
<section>
<h4>Size</h4>
<veui-radio-group
v-model="size"
:items="[
{ label: 'Medium', value: 'm' },
{ label: 'Small', value: 's' }
]"
/>
</section>
<section>
<veui-table
:ui="ui"
:data="data"
key-field="id"
>
<veui-table-column
field="id"
title="ID"
/>
<veui-table-column
field="name"
title="Name"
/>
<veui-table-column
field="bid"
title="Bid"
width="160"
align="right"
>
<template #default="{ bid }">
{{ bid | currency }}
</template>
</veui-table-column>
<veui-table-column
field="updateDate"
title="Last updated"
align="center"
>
<template #default="{ updateDate }">
{{ updateDate | date }}
</template>
</veui-table-column>
<veui-table-column
field="operation"
title="Operations"
>
<template #default="{ index }">
<veui-button
ui="text"
@click="remove(index)"
>
Remove
</veui-button>
</template>
</veui-table-column>
</veui-table>
</section>
</article>
</template>
<script>
import { Table, Column, RadioGroup, Button } from 'veui'
export default {
components: {
'veui-table': Table,
'veui-table-column': Column,
'veui-radio-group': RadioGroup,
'veui-button': Button
},
filters: {
currency (value) {
return '¥' + value.toFixed(2)
},
date (value) {
let [, ...parts] = value.match(/(\d{4})(\d{2})(\d{2})/) || []
return parts.join('-')
}
},
data () {
return {
density: 'normal',
size: 'm',
data: [
{
id: '3154',
name: 'Steve Rogers',
bid: 1024,
updateDate: '20131117'
},
{
id: '3155',
name: 'Thor Odinson',
bid: 598,
updateDate: '20140214'
},
{
id: '3156',
name: 'Tony Stark',
bid: 820,
updateDate: '20170610'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 736,
updateDate: '20180109'
}
]
}
},
computed: {
ui () {
return `${this.density} ${this.size}`
}
},
methods: {
remove (index) {
this.data.splice(index, 1)
}
}
}
</script>
<style lang="less" scoped>
section {
margin-bottom: 20px;
}
h4 {
margin-top: 0;
}
.veui-checkbox {
margin-right: 20px;
}
</style>
Selection and sorting
Supports specifying row keys, mode of selection, and sorting by values of specific column.
ID | Group | Name | Bid | Last updated | Opertaions | |
---|---|---|---|---|---|---|
3154 | 1577 | Steve Rogers | ¥1024.00 | 2013-11-17 | ||
3155 | Thor Odinson | ¥598.00 | 2014-02-14 | |||
3156 | 1578 | Tony Stark | ¥820.00 | 2017-06-10 | ||
3157 | Stephen Strange | ¥736.00 | 2018-01-09 |
Selected: ["1577"]
<template>
<article>
<section>
<veui-button
ui="primary"
@click="append"
>
Add
</veui-button>
</section>
<section>
<veui-checkbox
v-model="mode"
true-value="multiple"
false-value="single"
>
Multiple selection
</veui-checkbox>
<veui-checkbox v-model="showOps">
Display “Operations”
</veui-checkbox>
<veui-checkbox v-model="selectSpanRow">
Select by “Group” <small>(instead of “ID”)</small>
</veui-checkbox>
</section>
<section>
<veui-table
:data="data"
:key-field="selectSpanRow ? 'group' : 'id'"
selectable
:select-mode="mode"
:order-by="orderBy"
:order="order"
:selected.sync="selected"
@sort="handleSort"
>
<veui-table-column
field="id"
title="ID"
sortable
>
<template #head>
<strong>ID</strong>
</template>
<template #foot>
<strong>Total</strong>
</template>
</veui-table-column>
<veui-table-column
field="group"
title="Group"
:span="groupSpan"
/>
<veui-table-column
field="name"
title="Name"
width="160"
/>
<veui-table-column
field="bid"
title="Bid"
sortable
width="160"
align="right"
>
<template #default="{ bid }">
{{ bid | currency }}
</template>
<template #foot>
<strong>{{ total | currency }}</strong>
</template>
</veui-table-column>
<veui-table-column
field="updateDate"
title="Last updated"
align="center"
>
<template #default="{ id, updateDate }">
<span :ref="`time-a-${id}`">{{ updateDate | date }}</span>
<veui-tooltip :target="`time-a-${id}`">
{{ updateDate | time }}
</veui-tooltip>
</template>
</veui-table-column>
<veui-table-column
v-if="showOps"
field="operation"
title="Opertaions"
>
<template #default="{ index }">
<veui-button
ui="text"
@click="del(index)"
>
Remove
</veui-button>
</template>
</veui-table-column>
</veui-table>
<p>Selected: {{ JSON.stringify(selected) }}</p>
</section>
</article>
</template>
<script>
import { groupBy } from 'lodash'
import { Button, Checkbox, Table, Column, Tooltip } from 'veui'
export default {
components: {
'veui-button': Button,
'veui-table': Table,
'veui-table-column': Column,
'veui-tooltip': Tooltip,
'veui-checkbox': Checkbox
},
filters: {
currency (value) {
return '¥' + value.toFixed(2)
},
date (value) {
let [, ...parts] = value.match(/(\d{4})(\d{2})(\d{2})/) || []
return parts.join('-')
},
time (value) {
let [, ...parts] = value.match(/(\d{4})(\d{2})(\d{2})/) || []
return parts.join('-') + ' 00:00:00'
}
},
data () {
return {
mode: 'multiple',
showOps: true,
selectSpanRow: true,
data: [
{
id: '3154',
name: 'Steve Rogers',
bid: 1024,
updateDate: '20131117',
group: '1577'
},
{
id: '3155',
name: 'Thor Odinson',
bid: 598,
updateDate: '20140214',
group: '1577'
},
{
id: '3156',
name: 'Tony Stark',
bid: 820,
updateDate: '20170610',
group: '1578'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 736,
updateDate: '20180109',
group: '1578'
}
],
nextId: 3158,
nextIndex: 4,
order: false,
orderBy: null,
selected: ['1577'],
groupSpan: i => {
let groups = groupBy(this.data, 'group')
let item = this.data[i]
let itemGroup = groups[item.group]
if (item.id === (itemGroup[0] || {}).id) {
return {
row: itemGroup.length
}
}
return {
row: 0
}
}
}
},
computed: {
total () {
return this.data.reduce((total, item) => {
return total + item.bid
}, 0)
}
},
methods: {
del (index) {
this.data.splice(index, 1)
},
append () {
let d = new Date(Date.now() + Math.floor(Math.random() * 1e10))
let item = {
id: String(this.nextId),
group: String(Math.floor(this.nextId / 2)),
name: `Character-${this.nextIndex}`,
bid: Math.floor(Math.random() * 1280),
updateDate:
d.getFullYear() +
String(d.getMonth() + 1).padStart(2, '0') +
String(d.getMonth() + 1).padStart(2, '0')
}
this.nextId++
this.nextIndex++
this.data.push(item)
},
handleSort (orderBy, order) {
this.orderBy = orderBy
this.order = order
}
}
}
</script>
<style lang="less" scoped>
section {
margin-bottom: 20px;
}
.veui-checkbox {
margin-right: 20px;
}
</style>
Filter
Use the filter
slot of the Column
component to enable custom column filter dropdown.
Layout
ID | Name | Bid | Last updated | Operations |
---|---|---|---|---|
3154 | Steve Rogers | ¥1024.00 | 2013-11-17 | |
3155 | Thor Odinson | ¥598.00 | 2014-02-14 | |
3156 | Tony Stark | ¥820.00 | 2017-06-10 | |
3157 | Stephen Strange | ¥736.00 | 2018-01-09 |
You can use the ui
prop value crowded
to hide filter button by default when there are too many columns to be displayed.
<template>
<article>
<section>
<h4>Layout</h4>
<veui-checkbox v-model="crowded">
Crowded layout
</veui-checkbox>
</section>
<section>
<veui-table
:ui="crowded ? 'crowded' : null"
:data="filteredData"
key-field="id"
>
<veui-table-column
field="id"
title="ID"
/>
<veui-table-column
field="name"
title="Name"
/>
<veui-table-column
field="bid"
title="Bid"
width="160"
align="right"
:filter-value="filtered || null"
>
<template #default="{ bid }">
{{ bid | currency }}
</template>
<template #filter="{ close }">
<veui-checkbox v-model="filtered">
&gt;800
</veui-checkbox>
</template>
</veui-table-column>
<veui-table-column
field="updateDate"
title="Last updated"
align="center"
>
<template #default="{ updateDate }">
{{ updateDate | date }}
</template>
</veui-table-column>
<veui-table-column
field="operation"
title="Operations"
>
<template #default="{ index }">
<veui-button
ui="text"
@click="remove(index)"
>
Remove
</veui-button>
</template>
</veui-table-column>
</veui-table>
</section>
</article>
</template>
<script>
import { Table, Column, Checkbox, Button } from 'veui'
export default {
components: {
'veui-table': Table,
'veui-table-column': Column,
'veui-checkbox': Checkbox,
'veui-button': Button
},
filters: {
currency (value) {
return '¥' + value.toFixed(2)
},
date (value) {
let [, ...parts] = value.match(/(\d{4})(\d{2})(\d{2})/) || []
return parts.join('-')
}
},
data () {
return {
data: [
{
id: '3154',
name: 'Steve Rogers',
bid: 1024,
updateDate: '20131117'
},
{
id: '3155',
name: 'Thor Odinson',
bid: 598,
updateDate: '20140214'
},
{
id: '3156',
name: 'Tony Stark',
bid: 820,
updateDate: '20170610'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 736,
updateDate: '20180109'
}
],
crowded: false,
filtered: null
}
},
computed: {
filteredData () {
if (!this.filtered) {
return this.data
}
return this.data.filter(({ bid }) => bid > 800)
}
},
methods: {
remove (index) {
this.data.splice(index, 1)
}
}
}
</script>
<style lang="less" scoped>
.veui-checkbox {
margin: 8px 16px;
}
section {
margin-bottom: 20px;
}
h4 {
margin-top: 0;
}
</style>
Scroll inside
Allow table content to be scrollable inside the table body, i.e. the effect of fixed head/foot.
ID | Name | Bid | Last updated |
---|
3154 | Steve Rogers | ¥1024.00 | 2013-11-17 |
3155 | Thor Odinson | ¥598.00 | 2014-02-14 |
3156 | Tony Stark | ¥820.00 | 2017-06-10 |
3157 | Stephen Strange | ¥736.00 | 2018-01-09 |
3158 | Natalie Romanoff | ¥736.00 | 2018-01-23 |
3159 | Bruce Banner | ¥736.00 | 2018-12-01 |
3160 | Peter Parker | ¥736.00 | 2018-11-13 |
3161 | T'Challa | ¥736.00 | 2018-07-30 |
3162 | Loki | ¥736.00 | 2018-06-01 |
<template>
<article>
<section>
<veui-table
:data="data"
scroll="360"
key-field="id"
>
<veui-table-column
field="id"
title="ID"
/>
<veui-table-column
field="name"
title="Name"
/>
<veui-table-column
field="bid"
title="Bid"
width="160"
align="right"
>
<template #default="{ bid }">
{{ bid | currency }}
</template>
</veui-table-column>
<veui-table-column
field="updateDate"
title="Last updated"
align="center"
>
<template #default="{ updateDate }">
{{ updateDate | date }}
</template>
</veui-table-column>
</veui-table>
</section>
</article>
</template>
<script>
import { Table, Column } from 'veui'
export default {
components: {
'veui-table': Table,
'veui-table-column': Column
},
filters: {
currency (value) {
return '¥' + value.toFixed(2)
},
date (value) {
let [, ...parts] = value.match(/(\d{4})(\d{2})(\d{2})/) || []
return parts.join('-')
}
},
data () {
return {
data: [
{
id: '3154',
name: 'Steve Rogers',
bid: 1024,
updateDate: '20131117'
},
{
id: '3155',
name: 'Thor Odinson',
bid: 598,
updateDate: '20140214'
},
{
id: '3156',
name: 'Tony Stark',
bid: 820,
updateDate: '20170610'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 736,
updateDate: '20180109'
},
{
id: '3158',
name: 'Natalie Romanoff',
bid: 736,
updateDate: '20180123'
},
{
id: '3159',
name: 'Bruce Banner',
bid: 736,
updateDate: '20181201'
},
{
id: '3160',
name: 'Peter Parker',
bid: 736,
updateDate: '20181113'
},
{
id: '3161',
name: "T'Challa",
bid: 736,
updateDate: '20180730'
},
{
id: '3162',
name: 'Loki',
bid: 736,
updateDate: '20180601'
}
]
}
}
}
</script>
<style lang="less" scoped>
section {
margin-bottom: 20px;
}
</style>
Fixed columns
Use the scroll
of Table
and the fixed
prop of Column
to enable fixed columns.
ID | Characters | Bid | Last updated | Operations | |
---|---|---|---|---|---|
Name | Title | ||||
3154 | Steve Rogers | Captain America | ¥1024.00 | 2013-11-17 | |
3155 | Thor Odinson | God of Thunder | ¥598.00 | 2014-02-14 | |
3156 | Tony Stark | Ironman | ¥820.00 | 2017-06-10 | |
3157 | Stephen Strange | Doctor Strange | ¥736.00 | 2018-01-09 |
The width
prop must be specified for fixed columns.
<template>
<article>
<veui-table
:data="data"
key-field="id"
:scroll="{ x: 800 }"
>
<veui-table-column
field="id"
title="ID"
width="80"
fixed="left"
/>
<veui-table-column title="Characters">
<veui-table-column
field="name"
title="Name"
width="200"
/>
<veui-table-column
field="title"
title="Title"
width="200"
/>
</veui-table-column>
<veui-table-column
field="bid"
title="Bid"
width="160"
align="right"
>
<template #default="{ bid }">
{{ bid | currency }}
</template>
</veui-table-column>
<veui-table-column
field="updateDate"
title="Last updated"
align="center"
width="200"
>
<template #default="{ updateDate }">
{{ updateDate | date }}
</template>
</veui-table-column>
<veui-table-column
field="operation"
title="Operations"
width="140"
fixed="right"
>
<template #default="{ index }">
<veui-button
ui="text"
@click="remove(index)"
>
Remove
</veui-button>
</template>
</veui-table-column>
</veui-table>
</article>
</template>
<script>
import { Table, Column, Button } from 'veui'
export default {
components: {
'veui-table': Table,
'veui-table-column': Column,
'veui-button': Button
},
filters: {
currency (value) {
return '¥' + value.toFixed(2)
},
date (value) {
let [, ...parts] = value.match(/(\d{4})(\d{2})(\d{2})/) || []
return parts.join('-')
}
},
data () {
return {
data: [
{
id: '3154',
name: 'Steve Rogers',
bid: 1024,
title: 'Captain America',
updateDate: '20131117'
},
{
id: '3155',
name: 'Thor Odinson',
bid: 598,
title: 'God of Thunder',
updateDate: '20140214'
},
{
id: '3156',
name: 'Tony Stark',
bid: 820,
title: 'Ironman',
updateDate: '20170610'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 736,
title: 'Doctor Strange',
updateDate: '20180109'
}
]
}
},
methods: {
remove (index) {
this.data.splice(index, 1)
}
}
}
</script>
<style lang="less" scoped>
section {
margin-bottom: 20px;
}
h4 {
margin-top: 0;
}
.veui-checkbox {
margin-right: 20px;
}
</style>
Expandable row
Rows can be expanded into sub-rows.
ID | Name | Bid | Last updated | |
---|---|---|---|---|
3154 | Steve Rogers | ¥1024.00 | 2013-11-17 | |
3155 | Thor Odinson | ¥598.00 | 2014-02-14 | |
3156 | Tony Stark | ¥820.00 | 2017-06-10 | |
3157 | Stephen Strange | ¥736.00 | 2018-01-09 |
<template>
<article>
<section>
<veui-table
:data="data"
expandable
key-field="id"
>
<veui-table-column
field="id"
title="ID"
/>
<veui-table-column
field="name"
title="Name"
/>
<veui-table-column
field="bid"
title="Bid"
width="160"
align="right"
>
<template #default="{ bid }">
{{ bid | currency }}
</template>
</veui-table-column>
<veui-table-column
field="updateDate"
title="Last updated"
align="center"
>
<template #default="{ updateDate }">
{{ updateDate | date }}
</template>
</veui-table-column>
</veui-table>
</section>
</article>
</template>
<script>
import { Table, Column } from 'veui'
export default {
components: {
'veui-table': Table,
'veui-table-column': Column
},
filters: {
currency (value) {
return '¥' + value.toFixed(2)
},
date (value) {
let [, ...parts] = value.match(/(\d{4})(\d{2})(\d{2})/) || []
return parts.join('-')
}
},
data () {
return {
data: [
{
id: '3154',
name: 'Steve Rogers',
bid: 1024,
updateDate: '20131117',
children: [
{
id: '3154',
name: 'Steve Rogers',
bid: 1024,
updateDate: '20131117'
},
{
id: '3154',
name: 'Steve Rogers',
bid: 1001,
updateDate: '20131116'
},
{
id: '3154',
name: 'Steve Rogers',
bid: 985,
updateDate: '20131115'
}
]
},
{
id: '3155',
name: 'Thor Odinson',
bid: 598,
updateDate: '20140214',
children: [
{
id: '3155',
name: 'Thor Odinson',
bid: 520,
updateDate: '20131116'
}
]
},
{
id: '3156',
name: 'Tony Stark',
bid: 820,
updateDate: '20170610',
children: [
{
id: '3156',
name: 'Tony Stark',
bid: 800,
updateDate: '20131116'
},
{ id: '3156', name: 'Tony Stark', bid: 763, updateDate: '20131115' }
]
},
{
id: '3157',
name: 'Stephen Strange',
bid: 736,
updateDate: '20180109',
children: [
{
id: '3157',
name: 'Stephen Strange',
bid: 704,
updateDate: '20131116'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 666,
updateDate: '20131112'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 521,
updateDate: '20131111'
},
{
id: '3157',
name: 'Stephen Strange',
bid: 428,
updateDate: '20131110'
}
]
}
]
}
}
}
</script>
<style lang="less" scoped>
section {
margin-bottom: 20px;
}
</style>
Header descriptions
Use the desc
prop or the desc
slot to provide description for the column header.
ID | Name | Bid |
---|---|---|
31541 | Steve Rogers | ¥1024.00 |
31552 | Thor Odinson | ¥598.00 |
31563 | Tony Stark | ¥820.00 |
31574 | Stephen Strange | ¥736.00 |
<template>
<article>
<section>
<veui-table
:data="data"
key-field="id"
>
<veui-table-column
field="id"
title="ID"
/>
<veui-table-column
field="name"
title="Name"
:desc="nameDesc"
/>
<veui-table-column
field="bid"
title="Bid"
width="160"
align="right"
>
<template #default="{ bid }">
{{ bid | currency }}
</template>
<template #desc="{ close }">
<p>This is a description for bid.</p>
<veui-button @click="close">
close
</veui-button>
</template>
</veui-table-column>
</veui-table>
</section>
</article>
</template>
<script>
import { Table, Column, Button } from 'veui'
export default {
components: {
'veui-table': Table,
'veui-table-column': Column,
'veui-button': Button
},
filters: {
currency (value) {
return '¥' + value.toFixed(2)
}
},
data () {
return {
data: [
{
id: '31541',
name: 'Steve Rogers',
bid: 1024,
updateDate: '20131117'
},
{
id: '31552',
name: 'Thor Odinson',
bid: 598,
updateDate: '20140214'
},
{
id: '31563',
name: 'Tony Stark',
bid: 820,
updateDate: '20170610'
},
{
id: '31574',
name: 'Stephen Strange',
bid: 736,
updateDate: '20180109'
}
],
nameDesc: 'This is a description for name.'
}
}
}
</script>
<style lang="less" scoped>
section {
margin-bottom: 20px;
}
h4 {
margin-top: 0;
}
</style>
Truncation tooltips
Use the tooltip
attribute of the Column
component to specify that a hover tooltip is displayed when the content is truncated.
ID | Name | Description |
---|---|---|
3154 | Steve Rogers | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos, quibusdam! Pariatur, laboriosam? Voluptatibus, sunt. |
3155 | Thor Odinson | Lorem ipsum. |
3156 | Tony Stark | Lorem ipsum. |
3157 | Stephen Strange | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos, quibusdam! Pariatur, laboriosam? Voluptatibus, sunt. |
<template>
<article>
<veui-table
:data="data"
key-field="id"
>
<veui-table-column
field="id"
title="ID"
/>
<veui-table-column
field="name"
title="Name"
/>
<veui-table-column
field="desc"
title="Description"
tooltip
/>
</veui-table>
</article>
</template>
<script>
import { Table, Column } from 'veui'
const long = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos, quibusdam! Pariatur, laboriosam? Voluptatibus, sunt.'
const short = 'Lorem ipsum.'
export default {
components: {
'veui-table': Table,
'veui-table-column': Column
},
data () {
return {
density: 'normal',
size: 'm',
data: [
{
id: '3154',
name: 'Steve Rogers',
desc: long
},
{
id: '3155',
name: 'Thor Odinson',
desc: short
},
{
id: '3156',
name: 'Tony Stark',
desc: short
},
{
id: '3157',
name: 'Stephen Strange',
desc: long
}
]
}
}
}
</script>
]
API
Props
Name | Type | Default | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ui | string= | - | Style variants.
| ||||||||||
data | Array<Object> | - | Table data in rows. | ||||||||||
key-field | string | - | Denotes the unique key of the table data. The value should be a key defined in the data object of each row. The corresponding field will be regarded as the key attribute for each row element. When selectable is true , it also indicates the rows of which column should be selected from (and in this occasion the value should be defined as the field prop for one of the children Column components). | ||||||||||
selectable | boolean | false | Whether the rows are selectable. | ||||||||||
select-mode | string | 'multiple' | The mode of row selection. Available values are single / multiple , which denote single selection and multiple selection respectively. | ||||||||||
selected | Array<*>|* | [] |
The value(s) of selected rows. When | ||||||||||
expandable | boolean | false | Whether the rows can be expanded into sub-rows. | ||||||||||
expanded | Array<*> | [] |
The values of expanded rows. Each item is the value keyed by the | ||||||||||
order | string | boolean | false | The order for sorting the specified column. false denotes no specific order, while string values of 'asc' / 'desc' denote ascending/descending order respectively. | ||||||||||
order-by | string | - | The column which is currently sorted by. The value should be defined as the field prop for one of the children Column components. | ||||||||||
scroll | number | - | The maximun height of the scrollable area inside the table body. When table content exceeds the specified height, internal scroll will be enabled and the head/foot will become fixed. | ||||||||||
loading | boolean | false | Whether table data is being loaded. |
Slots
Name | Description |
---|---|
default | The columns of the table. Can only have Column components as children. |
no-data | The content to be displayed when there's no data to show. |
foot | The content of the table foot. Will span across all columns when defined. |
sub-row | The content of the expanded sub-row. Will span across all columns and override the The slot scope properties are the same as each item inside |
Events
Name | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
select | Triggered when the selected item(s) are changed. The callback parameter list is
| ||||||||||||
sort | Triggered when users sort a specific column. The callback parameter list is |