彈出視窗是一個容器元件,可以在頁面上覆蓋其他元件。
import Popover from 'primevue/popover';
彈出視窗透過其 ref 存取,並且可使用目標事件的 toggle、show 和 hide 函式來控制可見性。
<Button type="button" icon="pi pi-share-alt" label="Share" @click="toggle" />
<Popover ref="op">
<div class="flex flex-col gap-4 w-[25rem]">
<div>
<span class="font-medium block mb-2">Share this document</span>
<InputGroup>
<InputText value="https://primevue.dev.org.tw/12323ff26t2g243g423g234gg52hy25XADXAG3" readonly class="w-[25rem]"></InputText>
<InputGroupAddon>
<i class="pi pi-copy"></i>
</InputGroupAddon>
</InputGroup>
</div>
<div>
<span class="font-medium block mb-2">Invite Member</span>
<InputGroup>
<InputText disabled />
<Button label="Invite" icon="pi pi-users"></Button>
</InputGroup>
</div>
<div>
<span class="font-medium block mb-2">Team Members</span>
<ul class="list-none p-0 m-0 flex flex-col gap-4">
<li v-for="member in members" :key="member.name" class="flex items-center gap-2">
<img :src="`https://primefaces.org/cdn/primevue/images/avatar/${member.image}`" style="width: 32px" />
<div>
<span class="font-medium">{{ member.name }}</span>
<div class="text-sm text-surface-500 dark:text-surface-400">{{ member.email }}</div>
</div>
<div class="flex items-center gap-2 text-surface-500 dark:text-surface-400 ml-auto text-sm">
<span>{{ member.role }}</span>
<i class="pi pi-angle-down"></i>
</div>
</li>
</ul>
</div>
</div>
</Popover>
在此範例中,資料是從彈出視窗內的內容擷取的。
<Button type="button" :label="selectedMember ? selectedMember.name : 'Select Member'" @click="toggle" class="min-w-48" />
<Popover ref="op">
<div class="flex flex-col gap-4">
<div>
<span class="font-medium block mb-2">Team Members</span>
<ul class="list-none p-0 m-0 flex flex-col">
<li v-for="member in members" :key="member.name" class="flex items-center gap-2 px-2 py-3 hover:bg-emphasis cursor-pointer rounded-border" @click="selectMember(member)">
<img :src="`https://primefaces.org/cdn/primevue/images/avatar/${member.image}`" style="width: 32px" />
<div>
<span class="font-medium">{{ member.name }}</span>
<div class="text-sm text-surface-500 dark:text-surface-400">{{ member.email }}</div>
</div>
</li>
</ul>
</div>
</div>
</Popover>
將彈出視窗放置在資料迭代元件之外,以避免多次渲染。
Id | 代碼 | 名稱 | 價格 | 圖片 | 詳細資料 |
---|
<DataTable :value="products" :rows="5" paginator tableStyle="min-width: 50rem">
<Column field="id" header="Id" class="w-1/6"></Column>
<Column field="code" header="Code" class="w-1/6"></Column>
<Column field="name" header="Name" class="w-1/6" bodyClass="whitespace-nowrap"></Column>
<Column field="price" header="Price" sortable class="w-1/6">
<template #body="slotProps"> $ {{ slotProps.data.price }} </template>
</Column>
<Column header="Image" class="w-1/6">
<template #body="slotProps">
<img :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.data.image}`" :alt="slotProps.data.image" class="w-16 shadow-sm" />
</template>
</Column>
<Column header="Details" class="w-1/6">
<template #body="slotProps">
<Button type="button" @click="displayProduct($event, slotProps.data)" icon="pi pi-search" severity="secondary" rounded></Button>
</template>
</Column>
</DataTable>
<Popover ref="op">
<div v-if="selectedProduct" class="rounded flex flex-col">
<div class="flex justify-center rounded">
<div class="relative mx-auto">
<img class="rounded w-44 sm:w-64" :src="`https://primefaces.org/cdn/primevue/images/product/${selectedProduct.image}`" :alt="selectedProduct.name" />
<Tag :value="selectedProduct.inventoryStatus" :severity="getSeverity(selectedProduct)" class="absolute dark:!bg-surface-900" style="left: 4px; top: 4px"></Tag>
</div>
</div>
<div class="pt-4">
<div class="flex flex-row justify-between items-start gap-2 mb-4">
<div>
<span class="font-medium text-surface-500 dark:text-surface-400 text-sm">{{ selectedProduct.category }}</span>
<div class="text-lg font-medium mt-1">{{ selectedProduct.name }}</div>
</div>
<div class="bg-surface-100 p-1" style="border-radius: 30px">
<div class="bg-surface-0 flex items-center gap-2 justify-center py-1 px-2" style="border-radius: 30px; box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.04), 0px 1px 2px 0px rgba(0, 0, 0, 0.06)">
<span class="text-surface-900 font-medium text-sm">{{ selectedProduct.rating }}</span>
<i class="pi pi-star-fill text-yellow-500"></i>
</div>
</div>
</div>
<div class="flex gap-2">
<Button icon="pi pi-shopping-cart" :label="`Buy Now | \$${selectedProduct.price}`" :disabled="selectedProduct.inventoryStatus === 'OUTOFSTOCK'" class="flex-auto whitespace-nowrap" @click="hidePopover"></Button>
<Button icon="pi pi-heart" outlined @click="hidePopover"></Button>
</div>
</div>
</div>
</Popover>
彈出視窗元件使用 dialog 角色,並且由於任何屬性都傳遞到根元素,您可以定義像是 aria-label 或 aria-labelledby 的屬性來描述彈出視窗的內容。此外,由於焦點保留在彈出視窗內,因此會加入 aria-modal。
彈出視窗將 aria-expanded 狀態屬性和 aria-controls 新增至觸發器,以便定義觸發器和彈出視窗之間的關係。
當彈出視窗開啟時,第一個可聚焦的元素會接收焦點,並且可以透過將 autofocus 新增至彈出視窗內的元素來自訂此行為。
按鍵 | 功能 |
---|---|
tab | 將焦點移至彈出視窗內的下一個可聚焦元素。 |
shift + tab | 將焦點移至彈出視窗內的前一個可聚焦元素。 |
escape | 關閉彈出視窗並將焦點移至觸發器。 |