弹出框

弹出框是一个容器组件,可以在页面上覆盖其他组件。


import Popover from 'primevue/popover';

通过其 ref 访问弹出框,并使用目标事件的 toggleshowhide 函数控制其可见性。


<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.org.cn/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-labelaria-labelledby 之类的属性来描述弹出窗口的内容。此外,由于焦点保持在弹出窗口内,因此会添加 aria-modal

弹出框将 aria-expanded 状态属性和 aria-controls 添加到触发器,以便定义触发器和弹出窗口之间的关系。

弹出框键盘支持

当弹出窗口打开时,第一个可聚焦元素会获得焦点,这可以通过将 autofocus 添加到弹出窗口中的元素来自定义。

功能
tab将焦点移动到弹出窗口内的下一个可聚焦元素。
shift + tab将焦点移动到弹出窗口内的上一个可聚焦元素。
escape关闭弹出窗口并将焦点移动到触发器。