Vitral 0.2
Dados

DataView

Ordenação e paginação sobre um template seu para cada item, exibido em lista ou em grade.

Importação

main.ts
import { DataView } from '@vitral/vue';

Lista e grade

Bamboo Watch 1
Bamboo Watch 1Accessories
$20In stock
Gold Necklace 6
Gold Necklace 6Clothing
$25Out
Gaming Set 11
Gaming Set 11Fitness
$30Low
Game Controller 16
Game Controller 16Electronics
$35In stock
Blue Band 21
Blue Band 21Accessories
$40Out
Black Jacket 2
Black Jacket 2Clothing
$57Low
<script setup lang="ts">import { Button, DataView, SelectButton, Tag } from '@vitral/vue';import { ref } from 'vue'; interface Product {    id: number;    name: string;    category: string;    price: number;    stock: 'In stock' | 'Low' | 'Out';    image: number;} const categories = ['Accessories', 'Clothing', 'Fitness', 'Electronics'];const products: Product[] = Array.from({ length: 24 }, (_, i) => ({    id: i,    name: ['Bamboo Watch', 'Black Jacket', 'Blue Band', 'Game Controller', 'Gaming Set', 'Gold Necklace'][i % 6]! + ` ${i + 1}`,    category: categories[i % 4]!,    price: 20 + ((i * 37) % 180),    stock: (['In stock', 'Low', 'Out'] as const)[i % 3]!,    image: 20 + i})); const layout = ref<'list' | 'grid'>('grid');const sortOrder = ref<1 | -1>(1);const severity = (stock: Product['stock']) => (stock === 'In stock' ? 'success' : stock === 'Low' ? 'warn' : 'danger');</script> <template>    <DataView :value="products" :layout="layout" paginator :rows="6" sort-field="price" :sort-order="sortOrder" data-key="id">        <template #header>            <div style="display: flex; justify-content: space-between; align-items: center; gap: 0.5rem">                <Button :label="sortOrder === 1 ? 'Price: low to high' : 'Price: high to low'" icon="sort" severity="secondary" variant="text" @click="sortOrder = sortOrder === 1 ? -1 : 1" />                <SelectButton v-model="layout" :options="['list', 'grid']" :allow-empty="false" aria-label="Layout" />            </div>        </template>        <template #list="{ items }">            <ul style="margin: 0; padding: 0; list-style: none">                <li v-for="p in items as Product[]" :key="p.id" style="display: flex; align-items: center; gap: 1rem; padding: 0.75rem 1rem; border-bottom: 1px solid var(--vt-content-border-color)">                    <img :src="`https://picsum.photos/id/${p.image}/96/96`" alt="" width="48" height="48" style="border-radius: 6px" />                    <div style="flex: 1">                        <strong>{{ p.name }}</strong>                        <div style="font-size: 0.75rem; color: var(--vt-text-muted-color)">{{ p.category }}</div>                    </div>                    <Tag :value="p.stock" :severity="severity(p.stock)" />                    <span style="width: 4rem; text-align: end">${{ p.price }}</span>                </li>            </ul>        </template>        <template #grid="{ items }">            <article v-for="p in items as Product[]" :key="p.id" style="border: 1px solid var(--vt-content-border-color); border-radius: 8px; overflow: hidden">                <img :src="`https://picsum.photos/id/${p.image}/320/200`" :alt="p.name" style="display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover" />                <div style="padding: 0.75rem; display: flex; flex-direction: column; gap: 0.25rem">                    <strong>{{ p.name }}</strong>                    <small style="color: var(--vt-text-muted-color)">{{ p.category }}</small>                    <div style="display: flex; justify-content: space-between; align-items: center">                        <span>${{ p.price }}</span>                        <Tag :value="p.stock" :severity="severity(p.stock)" />                    </div>                </div>            </article>        </template>    </DataView></template>

API

Lido de packages/vue/src/components/DataView/types.ts, então diz o que o componente aceita de fato.

Props

NomeTipoDescrição
valueany[]Os itens; com `lazy`, só os da página atual.
layout'list' | 'grid'Qual template renderiza os itens: `list` (o padrão) ou `grid`.
dataKeystringUm campo que identifica um item.
sortFieldstringOrdena por este campo…
sortOrder1 | -1 | 0…crescente (1) ou decrescente (-1).
paginatorboolean—
rowsnumberItens por página. O padrão é 12.
rowsPerPageOptionsnumber[]—
pageLinkSizenumber—
paginatorPosition'top' | 'bottom' | 'both'—
alwaysShowPaginatorboolean—
lazybooleanNada é calculado aqui: mudanças de página são emitidas (`page`) para a aplicação responder.
totalRecordsnumberO total de todas as páginas quando `lazy`.
loadingboolean—
emptyMessagestring—

Mais pt, dt e unstyled de BaseProps; veja pass-through e modo sem estilo.

Emits

EventoPayloadDescrição
pageevent: { page: number; first: number; rows: number; pageCount: number }—

Slots

NomeProps do slotDescrição
header——
footer——
list(props: { items: unknown[]; first: number })Os itens da página, no layout de lista.
grid(props: { items: unknown[]; first: number })Os itens da página, no layout de grade. Os elementos do slot são as células da grade.
empty——
loadingicon——