mirror of
https://github.com/nuxt/ui.git
synced 2026-09-14 19:51:10 +08:00
84 lines
1.5 KiB
Vue
84 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
import type { TableColumn } from '@nuxt/ui'
|
|
import { useInfiniteScroll } from '@vueuse/core'
|
|
|
|
const UAvatar = resolveComponent('UAvatar')
|
|
|
|
type User = {
|
|
id: number
|
|
firstName: string
|
|
username: string
|
|
email: string
|
|
image: string
|
|
}
|
|
|
|
type UserResponse = {
|
|
users: User[]
|
|
total: number
|
|
skip: number
|
|
limit: number
|
|
}
|
|
|
|
const skip = ref(0)
|
|
|
|
const { data, status } = useLazyFetch('https://dummyjson.com/users?limit=10&select=firstName,username,email,image', {
|
|
key: 'table-users-infinite-scroll',
|
|
params: { skip },
|
|
transform: (data?: UserResponse) => {
|
|
return data?.users
|
|
},
|
|
server: false
|
|
})
|
|
|
|
const columns: TableColumn<User>[] = [{
|
|
accessorKey: 'id',
|
|
header: 'ID'
|
|
}, {
|
|
accessorKey: 'image',
|
|
header: 'Avatar',
|
|
cell: ({ row }) => h(UAvatar, { src: row.original.image, loading: 'lazy' })
|
|
}, {
|
|
accessorKey: 'firstName',
|
|
header: 'First name'
|
|
}, {
|
|
accessorKey: 'email',
|
|
header: 'Email'
|
|
}, {
|
|
accessorKey: 'username',
|
|
header: 'Username'
|
|
}]
|
|
|
|
const users = ref<User[]>([])
|
|
|
|
watch(data, () => {
|
|
users.value = [
|
|
...users.value,
|
|
...(data.value || [])
|
|
]
|
|
})
|
|
|
|
const table = useTemplateRef('table')
|
|
|
|
onMounted(() => {
|
|
useInfiniteScroll(table.value?.$el, () => {
|
|
skip.value += 10
|
|
}, {
|
|
distance: 200,
|
|
canLoadMore: () => {
|
|
return status.value !== 'pending'
|
|
}
|
|
})
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<UTable
|
|
ref="table"
|
|
:data="users"
|
|
:columns="columns"
|
|
:loading="status === 'pending' || status === 'idle'"
|
|
sticky
|
|
class="flex-1 h-80"
|
|
/>
|
|
</template>
|