news 2026/9/15 22:17:39

PrimeNG Dock 组件完全指南:从基础导航到模拟桌面 UI 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PrimeNG Dock 组件完全指南:从基础导航到模拟桌面 UI 实战

PrimeNG Dock 组件完全指南:从基础导航到模拟桌面 UI 实战

【免费下载链接】primengThe Most Complete Angular UI Component Library项目地址: https://gitcode.com/GitHub_Trending/pr/primeng

Dock 是 PrimeNG 提供的一种导航组件,由一组菜单项(MenuItem)构成,形态类似于 macOS 的 Dock 栏,适合用作应用内的快捷导航或模拟桌面级操作界面。本文将以 apps/showcase/public/llms/components/dock.md 为核心骨架,结合 组件源码、样式定义、单元测试 与类型定义,完整讲解 Dock 的导入方式、基础与高级用法、全部 Props/Emits/Templates API、无障碍键盘支持、Pass Through 定制以及主题设计令牌,读完即可在 Angular 应用中落地一个可用的 Dock 导航。

Dock 是什么

Dock 是一个由菜单项(menuitems)组成的导航组件。它不依赖额外的第三方依赖,直接基于 PrimeNG 的MenuItem模型定义导航项,每个菜单项可以包含图标、标签、跳转链接或命令回调。从源码注释与官方文档描述(见 dock.ts 与 dockstyle.ts)可以确认,其核心定位是"navigation component consisting of menuitems"。

安装与导入

Dock 属于 PrimeNG 标准组件,无需单独安装额外包。在模块式应用中使用DockModule

import { DockModule } from 'primeng/dock';

该导入方式与 showcase 中的 import-doc.ts 完全一致。在 Angular 17+ 的 standalone 场景下,也可以直接导入Dock组件类(advanced 示例中import { Dock } from 'primeng/dock'的写法即是如此)。

快速上手的最小示例

import { Component, OnInit } from '@angular/core'; import { DockModule } from 'primeng/dock'; import { MenuItem } from 'primeng/api'; @Component({ selector: 'app-dock-demo', standalone: true, imports: [DockModule], template: ` <div class="dock-window"> <p-dock [model]="items"></p-dock> </div> ` }) export class DockDemo implements OnInit { items: MenuItem[] | undefined; ngOnInit() { this.items = [ { label: 'Finder', icon: 'https://primefaces.org/cdn/primeng/images/dock/finder.svg' }, { label: 'App Store', icon: 'https://primefaces.org/cdn/primeng/images/dock/appstore.svg' }, { label: 'Photos', icon: 'https://primefaces.org/cdn/primeng/images/dock/photos.svg' }, { label: 'Trash', icon: 'https://primefaces.org/cdn/primeng/images/dock/trash.png' } ]; } }

默认情况下 Dock 渲染在底部(position默认为bottom),并会根据模型自动生成菜单项。

基础用法:模型与定位

Dock 需要一个MenuItem[]集合作为其模型(model)。默认位置是底部(bottom),通过position属性还可以设置为其他三个方向:topleftright。Dock 的内容由item模板定义。

下面的 Basic 示例来自官方文档,通过单选按钮动态切换 Dock 的停靠方向,同时展示了item模板的用法:

import { Component, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { DockModule } from 'primeng/dock'; import { RadioButtonModule } from 'primeng/radiobutton'; import { TooltipModule } from 'primeng/tooltip'; import { MenuItem } from 'primeng/api'; @Component({ template: ` <div class="card"> <div class="flex flex-wrap gap-4 mb-8"> <div *ngFor="let pos of positionOptions" class="flex items-center"> <p-radiobutton name="dock" [value]="pos.value" [label]="pos.label" [(ngModel)]="position" [inputId]="pos.label" /> <label [for]="pos.label" class="ml-2"> {{ pos.label }} </label> </div> </div> <div class="dock-window"> <p-dock [model]="items" [position]="position"> <ng-template #item let-item> <img [pTooltip]="item.label" tooltipPosition="top" [src]="item.icon" [alt]="item.label" width="100%" /> </ng-template> </p-dock> </div> </div> `, standalone: true, imports: [DockModule, RadioButtonModule, TooltipModule, FormsModule] }) export class DockBasicDemo implements OnInit { items: MenuItem[] | undefined; positionOptions: any[]; ngOnInit() { this.items = [ { label: 'Finder', icon: 'https://primefaces.org/cdn/primeng/images/dock/finder.svg' }, { label: 'App Store', icon: 'https://primefaces.org/cdn/primeng/images/dock/appstore.svg' }, { label: 'Photos', icon: 'https://primefaces.org/cdn/primeng/images/dock/photos.svg' }, { label: 'Trash', icon: 'https://primefaces.org/cdn/primeng/images/dock/trash.png' } ]; } }

关键知识点

  • model属性MenuItem[]类型,默认值为null。菜单项支持的字段在 dock.ts 模板中有完整映射,包括labeliconurlrouterLinkcommanddisabledvisiblebadgestyleClasstooltipOptions等。
  • position属性:可选值为"right" | "left" | "top" | "bottom",默认bottom。从 dockstyle.ts 可以看到,根节点会根据当前 position 追加p-dock-bottom/p-dock-top/p-dock-left/p-dock-right类名。
  • item模板:通过<ng-template #item let-item>定义,item即当前MenuItem,模板上下文定义在 dock.types.ts 中($implicit: MenuItem)。不提供模板时,组件会默认渲染图标span(见 dock.ts)。

高级用法:用 Dock 组装一个模拟桌面 UI

Dock 的经典实战场景是模拟桌面操作系统界面。官方 Advanced 示例将 Dock 与 Menubar、Dialog、Tree、Terminal、Galleria、Toast、Tooltip 组合在一起,构建了一个带 Finder、Terminal、App Store、Safari、Photos、GitHub、Trash 图标的 macOS 风格 Dock。

import { Component, OnInit, inject } from '@angular/core'; import { DialogModule } from 'primeng/dialog'; import { DockModule } from 'primeng/dock'; import { GalleriaModule } from 'primeng/galleria'; import { MenubarModule } from 'primeng/menubar'; import { TerminalModule } from 'primeng/terminal'; import { ToastModule } from 'primeng/toast'; import { TreeModule } from 'primeng/tree'; import { TooltipModule } from 'primeng/tooltip'; import { NodeService } from '@/service/nodeservice'; import { PhotoService } from '@/service/photoservice'; import { MenuItem, MessageService } from 'primeng/api'; @Component({ template: ` <div class="card dock-demo"> <p-menubar [model]="menubarItems"> <ng-template #start> <i class="pi pi-apple px-2"></i> </ng-template> <ng-template #end> <i class="pi pi-video px-2"></i> <i class="pi pi-wifi px-2"></i> <i class="pi pi-volume-up px-2"></i> <span class="px-2">Fri 13:07</span> <i class="pi pi-search px-2"></i> <i class="pi pi-bars px-2"></i> </ng-template> </p-menubar> <div class="dock-window"> <p-dock [model]="dockItems" position="bottom"> <ng-template #item let-item> <a [pTooltip]="item.label" tooltipPosition="top" class="p-dock-item-link"> <img [alt]="item.label" [src]="item.icon" style="width: 100%" /> </a> </ng-template> </p-dock> <p-toast position="top-center" key="tc" /> <p-dialog [(visible)]="displayFinder" [breakpoints]="{ '960px': '50vw' }" [style]="{ width: '30vw', height: '18rem' }" [draggable]="false" [resizable]="false" header="Finder"> <p-tree [value]="nodes" /> </p-dialog> <p-dialog [maximizable]="true" [(visible)]="displayTerminal" [breakpoints]="{ '960px': '50vw' }" [style]="{ width: '30vw' }" [draggable]="false" [resizable]="false" header="Terminal"> <p-terminal welcomeMessage="Welcome to PrimeNG (cmd: 'date', 'greet {0}', 'random')" prompt="primeng $" /> </p-dialog> <p-galleria [(value)]="images" [showThumbnails]="false" [showThumbnailNavigators]="false" [showItemNavigators]="true" [(visible)]="displayGalleria" [circular]="true" [responsiveOptions]="responsiveOptions" [fullScreen]="true" [containerStyle]="{ width: '400px' }" > <ng-template #item let-item> <img [src]="item.itemImageSrc" style="width: 100%; display: block;" /> </ng-template> </p-galleria> </div> </div> `, standalone: true, imports: [DialogModule, DockModule, GalleriaModule, MenubarModule, TerminalModule, ToastModule, TreeModule, TooltipModule], providers: [NodeService, PhotoService, MessageService] }) export class DockAdvancedDemo implements OnInit { private nodeService = inject(NodeService); private photoService = inject(PhotoService); private messageService = inject(MessageService); displayTerminal: boolean | undefined; displayFinder: boolean | undefined; displayGalleria: boolean | undefined; dockItems: MenuItem[] | undefined; menubarItems: any[] | undefined; responsiveOptions: any[] | undefined; images: any[] | undefined; nodes: any[] | undefined; subscription: Subscription | undefined; ngOnInit() { this.dockItems = [ { label: 'Finder', tooltipOptions: { tooltipLabel: 'Finder', tooltipPosition: 'top', positionTop: -15, positionLeft: 15, showDelay: 1000 }, icon: 'https://primefaces.org/cdn/primeng/images/dock/finder.svg', command: () => { this.displayFinder = true; } }, { label: 'Terminal', tooltipOptions: { tooltipLabel: 'Terminal', tooltipPosition: 'top', positionTop: -15, positionLeft: 15, showDelay: 1000 }, icon: 'https://primefaces.org/cdn/primeng/images/dock/terminal.svg', command: () => { this.displayTerminal = true; } }, { label: 'App Store', tooltipOptions: { tooltipLabel: 'App Store', tooltipPosition: 'top', positionTop: -15, positionLeft: 15, showDelay: 1000 }, icon: 'https://primefaces.org/cdn/primeng/images/dock/appstore.svg', url: 'https://www.apple.com/app-store/' }, { label: 'Safari', tooltipOptions: { tooltipLabel: 'Safari', tooltipPosition: 'top', positionTop: -15, positionLeft: 15, showDelay: 1000 }, icon: 'https://primefaces.org/cdn/primeng/images/dock/safari.svg' }, { label: 'Photos', tooltipOptions: { tooltipLabel: 'Photos', tooltipPosition: 'top', positionTop: -15, positionLeft: 15, showDelay: 1000 }, icon: 'https://primefaces.org/cdn/primeng/images/dock/photos.svg', command: () => { this.displayGalleria = true; } }, { label: 'GitHub', tooltipOptions: { tooltipLabel: 'GitHub', tooltipPosition: 'top', positionTop: -15, positionLeft: 15, showDelay: 1000 }, icon: 'https://primefaces.org/cdn/primeng/images/dock/github.svg', url: 'https://github.com/primefaces/primeng' }, { label: 'Trash', tooltipOptions: { tooltipLabel: 'Trash', tooltipPosition: 'top', positionTop: -15, positionLeft: 15, showDelay: 1000 }, icon: 'https://primefaces.org/cdn/primeng/images/dock/trash.png', command: () => { this.messageService.add({ severity: 'info', summary: 'Trash is empty', key: 'tc' }); } } ]; this.menubarItems = [ { label: 'Finder', styleClass: 'menubar-root' }, { label: 'File', items: [ { label: 'New', icon: 'pi pi-fw pi-plus', items: [ { label: 'Bookmark', icon: 'pi pi-fw pi-bookmark' }, { label: 'Video', icon: 'pi pi-fw pi-video' } ] }, { label: 'Delete', icon: 'pi pi-fw pi-trash' }, { separator: true }, { label: 'Export', icon: 'pi pi-fw pi-external-link' } ] }, { label: 'Edit', items: [ { label: 'Left', icon: 'pi pi-fw pi-align-left' }, { label: 'Right', icon: 'pi pi-fw pi-align-right' }, { label: 'Center', icon: 'pi pi-fw pi-align-center' }, { label: 'Justify', icon: 'pi pi-fw pi-align-justify' } ] }, { label: 'Users', items: [ { label: 'New', icon: 'pi pi-fw pi-user-plus' }, { label: 'Delete', icon: 'pi pi-fw pi-user-minus' }, { label: 'Search', icon: 'pi pi-fw pi-users', items: [ { label: 'Filter', icon: 'pi pi-fw pi-filter', items: [ { label: 'Print', icon: 'pi pi-fw pi-print' } ] }, { icon: 'pi pi-fw pi-bars', label: 'List' } ] } ] }, { label: 'Events', items: [ { label: 'Edit', icon: 'pi pi-fw pi-pencil', items: [ { label: 'Save', icon: 'pi pi-fw pi-calendar-plus' }, { label: 'Delete', icon: 'pi pi-fw pi-calendar-minus' } ] }, { label: 'Archieve', icon: 'pi pi-fw pi-calendar-times', items: [ { label: 'Remove', icon: 'pi pi-fw pi-calendar-minus' } ] } ] }, { label: 'Quit' } ]; this.responsiveOptions = [ { breakpoint: '1024px', numVisible: 3 }, { breakpoint: '768px', numVisible: 2 }, { breakpoint: '560px', numVisible: 1 } ]; this.subscription = this.terminalService.commandHandler.subscribe((command) => this.commandHandler(command)); this.galleriaService.getImages().then((data) => (this.images = data)); this.nodeService.getFiles().then((data) => (this.nodes = data)); } commandHandler(text: any) { let response; let argsIndex = text.indexOf(' '); let command = argsIndex !== -1 ? text.substring(0, argsIndex) : text; switch (command) { case 'date': response = 'Today is ' + new Date().toDateString(); break; case 'greet': response = 'Hola ' + text.substring(argsIndex + 1) + '!'; break; case 'random': response = Math.floor(Math.random() * 100); break; default: response = 'Unknown command: ' + command; break; } if (response) { this.terminalService.sendResponse(response as string); } } ngOnDestroy() { if (this.subscription) { this.subscription.unsubscribe(); } } }

示例拆解与实战要点

  • 菜单项三种行为模型:Dock 的MenuItem支持三类点击行为——command回调(如 Finder 打开对话框、Trash 弹出 Toast 提示)、url外链跳转(如 App Store、GitHub 项)、routerLink路由跳转(组件源码 dock.ts 中对routerLink的渲染分支可作佐证)。命令回调通过onItemClick触发,参数为{ originalEvent, item }(见 dock.ts)。
  • Tooltip 集成:每个菜单项可通过tooltipOptions配置tooltipLabeltooltipPositionpositionToppositionLeftshowDelay等参数;模板中的[pTooltip]指令与菜单项的tooltipOptions是两种等价写法。
  • item模板的应用:示例用自定义模板把图标渲染为<img>,并给链接追加p-dock-item-link类,这与组件默认渲染的span图标(dock.ts)形成对比——当你需要自定义图标内容时就用模板覆盖。
  • 配合其他组件:Dock 本身只负责导航触发,真正的"窗口"由 Dialog(Finder/Terminal)、Galleria(Photos)等组件呈现,Toast 用于反馈(Trash 点击提示)。breakpoints配合numVisible可以控制 Galleria 在不同视口下显示的图片数量。
  • 终端交互TerminalService.commandHandler订阅用户输入,commandHandler解析并响应dategreet {0}random命令。注意:示例中使用了this.terminalServicethis.galleriaService,实际使用时需要通过构造函数或inject()注入TerminalServicePhotoServiceGalleriaServicePhotoService提供),并在ngOnDestroy中退订subscription以防内存泄漏。

API 参考:Props、Emits 与 Templates

以下三张表来自官方文档,与 dock.ts 中@Input/@Output声明一一对应。

Props

NameTypeDefaultDescription
dtInputSignal<Object>undefinedDefines scoped design tokens of the component.
unstyledInputSignal<boolean>undefinedIndicates whether the component should be rendered without styles.
ptInputSignal<DockPassThrough>undefinedUsed to pass attributes to DOM elements inside the component.
ptOptionsInputSignal<PassThroughOptions>undefinedUsed to configure passthrough(pt) options of the component.
idstring-Current id state as a string.
styleClassstring-Class of the element.(Deprecated)
modelMenuItem[]nullMenuModel instance to define the action items.
position"right" | "left" | "top" | "bottom"bottomPosition of element.
ariaLabelstring-Defines a string that labels the input for accessibility.
breakpointstring960pxThe breakpoint to define the maximum width boundary.
ariaLabelledBystring-Defines a string that labels the dropdown button for accessibility.

Emits

NameParametersDescription
onFocusevent: FocusEventCallback to execute when button is focused.
onBlurevent: FocusEventCallback to invoke when the component loses focus.

Templates

NameTypeDescription
itemTemplateRef<DockItemTemplateContext>Custom item template.

属性细节补充

  • id自动生成:未显式传入id时,组件在初始化阶段会通过uuid('pn_id_')生成形如pn_id_xxx的字符串 id(见 dock.ts),并作为ul列表元素的 id 与aria-activedescendant的定位依据。
  • styleClass已废弃:源码标注@deprecated since v20.0.0, use class instead(dock.ts),新代码应直接使用 Angular 的class绑定。
  • breakpoint响应式边界:默认960px,组件内部用window.matchMedia((max-width: ${this.breakpoint}))监听视口宽度,当命中时根节点会追加p-dock-mobile类(见 dock.ts 与 dockstyle.ts),移动端可借此切换为不同的布局样式。源码在组件销毁时会通过unbindMatchMediaListener解绑监听,避免内存泄漏(dock.ts)。
  • onFocus/onBlur:在列表获得/失去焦点时触发,焦点进入时内部还会把focusedOptionIndex重置为 0(见 dock.ts)。

无障碍与键盘导航

Screen Reader 下,Dock 组件使用menurole,并通过aria-orientation声明菜单方向;菜单的描述文字既可以通过aria-labelledby属性指定,也可以直接用aria-label提供。每个列表项(li)具有presentationrole,而其中的锚点(a)元素则具有menuitemrole,其aria-label指向菜单项的 label;当菜单项被禁用时,会设置aria-disabled

以上 ARIA 结构在 dock.ts 的模板中有直接实现:ul上绑定role="menu"aria-orientationaria-label/aria-labelledbyaria-activedescendanttabindexli上绑定role="menuitem"aria-labelaria-disabled;锚点绑定aria-hidden="true"。单元测试 dock.spec.ts 也验证了这些 ARIA 属性在四种 position 下aria-orientation的正确取值。

键盘支持

KeyFunction
tab焦点进入菜单时,将焦点加到第一个菜单项;若焦点已在菜单内,则移到页面 tab 序列的下一个可聚焦元素。
shift + tab焦点进入菜单时,将焦点加到最后一个菜单项;若焦点已在菜单内,则移到页面 tab 序列的上一个可聚焦元素。
enter激活当前聚焦的 menuitem。
space激活当前聚焦的 menuitem。
down arrow在垂直布局中,将焦点移到下一个 menuitem。
up arrow在垂直布局中,将焦点移到上一个 menuitem。
home在水平布局中,将焦点移到第一个 menuitem。
end在水平布局中,将焦点移到最后一个 menuitem。

键盘逻辑的源码实现

组件在onListKeyDown中根据event.code分派按键(dock.ts):

  • 方向键与布局联动:positionleft/right(垂直布局)时,ArrowDown/ArrowUp生效;positiontop/bottom(水平布局)时,ArrowRight/ArrowLeft生效。
  • Home跳转到索引 0,End通过查找最后一个data-p-disabled="false"的菜单项确定末尾索引。
  • EnterSpace均调用onSpaceKey:内部找到focusedOptionIndex对应的li,再查找其中的a,button元素并触发原生click()(dock.ts)。
  • 焦点移动只遍历data-p-disabled="false"的菜单项,即禁用的菜单项会被键盘导航自动跳过(findNextOptionIndex/findPrevOptionIndex,见 dock.ts)。
  • aria-activedescendant会在获得焦点后指向当前聚焦菜单项的 id,方便读屏软件播报。

这些行为在 dock.spec.ts 的"Keyboard Navigation Tests"中均有对应的单元测试覆盖。

Pass Through Options:细粒度定制 DOM

Pass Through(简称 pt)是 PrimeNG 提供的无样式定制机制,用于把属性、类名或事件直接传给组件内部的 DOM 元素。Dock 的 pt 选项定义在 dock.types.ts,与官方文档表完全一致:

NameTypeDescription
rootPassThroughOption<HTMLElement, I>Used to pass attributes to the root's DOM element.
listContainerPassThroughOption<HTMLDivElement, I>Used to pass attributes to the list container's DOM element.
listPassThroughOption<HTMLUListElement, I>Used to pass attributes to the list's DOM element.
itemPassThroughOption<HTMLLIElement, I>Used to pass attributes to the item's DOM element.
itemContentPassThroughOption<HTMLDivElement, I>Used to pass attributes to the item content's DOM element.
itemLinkPassThroughOption<HTMLAnchorElement, I>Used to pass attributes to the item link's DOM element.
itemIconPassThroughOption<HTMLSpanElement, I>Used to pass attributes to the item icon's DOM element.

组件在模板中通过ptm('listContainer')ptm('list')getPTOptions(item, i, 'item')等调用把 pt 选项应用到对应元素(dock.ts),其中 item 级别的 pt 还会携带{ item, index }上下文(getPTOptions,见 dock.ts),允许你按菜单项动态返回不同属性。配合unstyled属性使用,可以完全脱离预设样式,实现 headless 定制。

Theming:CSS 类与设计令牌

CSS Classes

组件 DOM 结构与样式类的对应关系定义在 dockstyle.ts,与官方文档表一致:

ClassDescription
p-dockClass name of the root element
p-dock-list-containerClass name of the list container element
p-dock-listClass name of the list element
p-dock-itemClass name of the item element
p-dock-item-contentClass name of the item content element
p-dock-item-linkClass name of the item link element
p-dock-item-iconClass name of the item icon element

此外还有两个随状态追加的类:根节点根据 position 追加p-dock-bottom等方向类、命中 breakpoint 时追加p-dock-mobile;菜单项获得焦点或禁用时追加p-focus/p-disableddata-pc-name="dock"属性会挂在组件宿主元素上,供自动化测试与 pt 选择器使用(测试见 dock.spec.ts)。

Design Tokens

TokenCSS VariableDescription
dock.background--p-dock-backgroundBackground of root
dock.border.color--p-dock-border-colorBorder color of root
dock.padding--p-dock-paddingPadding of root
dock.border.radius--p-dock-border-radiusBorder radius of root
dock.item.border.radius--p-dock-item-border-radiusBorder radius of item
dock.item.padding--p-dock-item-paddingPadding of item
dock.item.size--p-dock-item-sizeSize of item
dock.item.focus.ring.width--p-dock-item-focus-ring-widthFocus ring width of item
dock.item.focus.ring.style--p-dock-item-focus-ring-styleFocus ring style of item
dock.item.focus.ring.color--p-dock-item-focus-ring-colorFocus ring color of item
dock.item.focus.ring.offset--p-dock-item-focus-ring-offsetFocus ring offset of item
dock.item.focus.ring.shadow--p-dock-item-focus-ring-shadowFocus ring shadow of item

设计令牌统一以--p-dock-*CSS 变量形式暴露(实际样式值由@primeuix/styles/dock提供,见 dockstyle.ts)。你可以通过覆盖这些变量实现主题定制:例如修改--p-dock-background改变 Dock 底色、修改--p-dock-item-size调整图标尺寸、修改--p-dock-item-focus-ring-color定制键盘焦点高亮颜色。

从源码看 Dock 的内部机制

渲染分支:链接 vs 命令

组件对每个菜单项渲染为两种锚点分支(dock.ts):

  • 当菜单项定义了routerLink且未禁用时,渲染为 Angular Router 链接(routerLinkActive="router-link-active",支持queryParamsfragmentqueryParamsHandlingpreserveFragmentskipLocationChangereplaceUrlstate等路由属性);
  • 否则渲染为普通href链接(对应url字段)或纯点击项(对应command)。

isClickableRouterLink方法决定走哪个分支(dock.ts),对应测试见 dock.spec.ts。

菜单项渲染细节

  • visible: false隐藏@for循环内通过*ngIf="item.visible !== false"过滤隐藏项(dock.ts),测试见 dock.spec.ts。
  • disabled支持布尔与函数disabled(item)会先判断是否为函数,是则调用求值(dock.ts),禁用项同时带aria-disableddata-p-disabled属性。
  • badge徽标:菜单项可配置badgebadgeStyleClass,组件内置p-badge渲染角标(dock.ts)。
  • Ripple 水波纹:锚点应用了pRipple指令,点击时有水波纹反馈。
  • 动态模型:模型是响应式的,运行时增删菜单项会实时反映到 DOM,测试覆盖了 add/remove/clear 三种变更(dock.spec.ts)。

生命周期与平台适配

组件继承自BaseComponent,在onInit中生成 id 并绑定媒体查询监听,在onDestroy中解绑;onAfterViewChecked中把ptms(['host', 'root'])的 pt 属性同步到宿主元素(dock.ts)。整份 dock.spec.ts 共覆盖组件初始化、输入属性、位置与方向、交互、模板、键盘导航、焦点管理、样式、无障碍、路由集成、禁用项、动态模型、边界情况、媒体查询与公共方法等十余个测试分组,可作为自定义扩展时的参考基线。

总结

Dock 组件以MenuItem[]为唯一核心输入,通过position实现四向停靠,通过item模板实现完全自定义的图标内容,通过command/url/routerLink三种方式承载导航行为,并通过完整的 ARIA 结构与键盘导航(Enter/Space/方向键/Home/End)保证无障碍体验。配合breakpoint响应式切换、Pass Through 无样式定制以及--p-dock-*设计令牌,Dock 既可以直接落地为产品导航,也可以像 Advanced 示例那样与 Dialog、Galleria、Terminal、Toast 组合,快速搭建富有表现力的类桌面应用界面。想深入了解实现细节,可以继续阅读 dock.ts、dockstyle.ts、dock.types.ts 与 dock.spec.ts。

【免费下载链接】primengThe Most Complete Angular UI Component Library项目地址: https://gitcode.com/GitHub_Trending/pr/primeng

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 22:17:29

欧姆龙E6B2编码器STM32驱动:HAL库定时器编码器模式转速读取

简介&#xff1a;欧姆龙E6B2编码器驱动程序基于STM32F1系列与HAL库编写&#xff0c;面向工业自动化和嵌入式开发者&#xff0c;用于精确读取编码器转速与角度&#xff0c;适用于速度、位置反馈控制场景。资源包共215个文件&#xff0c;大小仅1.29MB&#xff0c;主要包含C/H源码…

作者头像 李华
网站建设 2026/9/15 22:16:01

Kuikly跨端实践:把DeepSeek Harness变成手机遥控器

一个周五晚上&#xff0c;我去楼下取快递&#xff0c;手机屏幕亮了好几次。不是消息&#xff0c;是我的 DeepSeek Harness 任务跑完了一轮&#xff0c;我本来想趁排队时间确认一下结果&#xff0c;结果发现手机里除了浏览器和聊天工具&#xff0c;根本没有一个能操作它的入口。…

作者头像 李华
网站建设 2026/9/15 22:15:01

嵌入式Linux标准IO实战:缓冲区、文件编程与日志模块

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 22:14:45

Unity Addressable Assets架构原理与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 22:14:07

Copula函数在风光联合出力场景生成中的应用

1. 项目背景与核心价值风光联合出力场景生成是新能源电力系统规划与运行中的关键环节。传统方法往往假设风电和光伏出力相互独立&#xff0c;这与实际观测数据中存在的明显相关性相矛盾。Copula函数作为一种描述变量间相关结构的强大工具&#xff0c;能够将边缘分布与相关性结构…

作者头像 李华