mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
feat(Table): add v-model:sort prop (#803)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<script setup>
|
||||
const sort = ref({
|
||||
column: 'name',
|
||||
direction: 'desc'
|
||||
})
|
||||
|
||||
const columns = [{
|
||||
key: 'id',
|
||||
label: 'ID'
|
||||
}, {
|
||||
key: 'name',
|
||||
label: 'Name',
|
||||
sortable: true
|
||||
}, {
|
||||
key: 'title',
|
||||
label: 'Title',
|
||||
sortable: true
|
||||
}, {
|
||||
key: 'email',
|
||||
label: 'Email'
|
||||
}, {
|
||||
key: 'role',
|
||||
label: 'Role',
|
||||
sortable: true,
|
||||
direction: 'desc'
|
||||
}]
|
||||
|
||||
const people = [{
|
||||
id: 1,
|
||||
name: 'Lindsay Walton',
|
||||
title: 'Front-end Developer',
|
||||
email: 'lindsay.walton@example.com',
|
||||
role: 'Member'
|
||||
}, {
|
||||
id: 2,
|
||||
name: 'Courtney Henry',
|
||||
title: 'Designer',
|
||||
email: 'courtney.henry@example.com',
|
||||
role: 'Admin'
|
||||
}, {
|
||||
id: 3,
|
||||
name: 'Tom Cook',
|
||||
title: 'Director of Product',
|
||||
email: 'tom.cook@example.com',
|
||||
role: 'Member'
|
||||
}, {
|
||||
id: 4,
|
||||
name: 'Whitney Francis',
|
||||
title: 'Copywriter',
|
||||
email: 'whitney.francis@example.com',
|
||||
role: 'Admin'
|
||||
}, {
|
||||
id: 5,
|
||||
name: 'Leonard Krasner',
|
||||
title: 'Senior Designer',
|
||||
email: 'leonard.krasner@example.com',
|
||||
role: 'Owner'
|
||||
}, {
|
||||
id: 6,
|
||||
name: 'Floyd Miles',
|
||||
title: 'Principal Designer',
|
||||
email: 'floyd.miles@example.com',
|
||||
role: 'Member'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable v-model:sort="sort" :columns="columns" :rows="people" />
|
||||
</template>
|
||||
@@ -66,7 +66,7 @@ componentProps:
|
||||
---
|
||||
::
|
||||
|
||||
You can specify the default direction of each column through the `direction` property. It can be either `asc` or `desc` and defaults to `asc`.
|
||||
You may specify the default direction of each column through the `direction` property. It can be either `asc` or `desc`, but it will default to `asc`.
|
||||
|
||||
You can specify a default sort for the table through the `sort` prop. It's an object with the following properties:
|
||||
|
||||
@@ -156,6 +156,44 @@ Use the `sort-desc-icon` prop to set a different icon or change it globally in `
|
||||
You can also customize the entire header cell, read more in the [Slots](#slots) section.
|
||||
::
|
||||
|
||||
#### Reactive sorting :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
|
||||
|
||||
Sometimes you will want to fetch new data depending on the sorted column and direction. You can use the `v-model:sort` to automatically update the `ref` reactive element every time the sorting changes on the Table. You may also use `@update:sort` to call your own function with the sorting data.
|
||||
|
||||
For example, we can take advantage of `useLazyRefresh` computed URL to automatically fetch the data depending on the sorting column and direction every time the `sort` reactive element changes.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// Ensure it uses `ref` instead of `reactive`.
|
||||
const sort = ref({
|
||||
column: 'name',
|
||||
direction: 'desc'
|
||||
})
|
||||
|
||||
const columns = [...]
|
||||
|
||||
const { data, pending } = useLazyFetch(() => {
|
||||
return `/api/users?orderBy=${sort.value.column}&order=${sort.value.direction}`
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable v-model:sort="sort" :loading="pending" :columns="columns" :rows="data" />
|
||||
</template>
|
||||
```
|
||||
|
||||
The initial value of `sort` will be respected as the initial sort column and direction, as well as each column default sorting direction.
|
||||
|
||||
::component-example{class="grid"}
|
||||
---
|
||||
padding: false
|
||||
overflowClass: 'overflow-x-auto'
|
||||
component: 'table-example-reactive-sorting'
|
||||
componentProps:
|
||||
class: 'flex-1'
|
||||
---
|
||||
::
|
||||
|
||||
### Selectable
|
||||
|
||||
Use a `v-model` to make the table selectable. The `v-model` will be an array of the selected rows.
|
||||
|
||||
@@ -152,7 +152,7 @@ export default defineComponent({
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
emits: ['update:modelValue', 'update:sort'],
|
||||
setup (props, { emit, attrs: $attrs }) {
|
||||
const { ui, attrs } = useUI('table', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||
|
||||
@@ -160,6 +160,8 @@ export default defineComponent({
|
||||
|
||||
const sort = ref(defu({}, props.sort, { column: null, direction: 'asc' }))
|
||||
|
||||
const defaultSort = { column: sort.value.column, direction: null }
|
||||
|
||||
const rows = computed(() => {
|
||||
if (!sort.value?.column) {
|
||||
return props.rows
|
||||
@@ -225,13 +227,15 @@ export default defineComponent({
|
||||
const direction = !column.direction || column.direction === 'asc' ? 'desc' : 'asc'
|
||||
|
||||
if (sort.value.direction === direction) {
|
||||
sort.value = defu({}, props.sort, { column: null, direction: 'asc' })
|
||||
sort.value = defu({}, defaultSort, { column: null, direction: 'asc' })
|
||||
} else {
|
||||
sort.value.direction = sort.value.direction === 'asc' ? 'desc' : 'asc'
|
||||
}
|
||||
} else {
|
||||
sort.value = { column: column.key, direction: column.direction || 'asc' }
|
||||
}
|
||||
|
||||
emit('update:sort', sort.value)
|
||||
}
|
||||
|
||||
function onSelect (row) {
|
||||
|
||||
@@ -87,7 +87,7 @@ export default defineComponent({
|
||||
},
|
||||
autofocusDelay: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
default: 100
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
|
||||
Reference in New Issue
Block a user