Skip to content
返回设计中心

命令面板(Cmd+K)

对所有动作和页面的键盘优先搜索 — 高级用户到一切的快捷方式。

UX 模式高级

为什么

高级用户厌离键盘点击过菜单。命令面板(Cmd+K)让其打字跳任何页、运行任何动作、插任何模板 — Linear/Notion/Raycast 标志特性。

Nielsen Norman Group 研究显示用户在离开前平均停留 10-15 秒。清晰的视觉层次和渐进式披露将任务完成率提高 40-60%。

何时使用

任何 >20 动作或页的生产力应用:编辑器、仪表板、管理工具。跳过简单营销站或单用途应用,其导航已明显。

如何做

1. 触发 — Cmd/Ctrl+K 开;Esc 关;全局监听非每页 2. 输入 — 单文本字段,模糊搜所有命令 3. 命令 — { id, title, shortcut?, run(), group } — 页、动作、设置、最近 4. 模糊搜 — fuse.js 或 uFuzzy;按近度 + 相关排;显前 8 5. 键盘 — ↑↓ 导航、Enter 运行、Esc 关、Tab 接受参数化命令参数 6. 分组 — 页、动作、设置、最近 — 列表中标签区段 7. 提示 — 每命令旁显快捷键("跳到收件箱 ⌘1")以可发现 8. 近度 — 最近用命令提顶;用户重跑同 5 动作

示例

import { Command } from "cmdk"; // Vercel/Linear 用的库 function CommandPalette() { const [open, setOpen] = useState(false); useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "k" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); setOpen((o) => !o); } }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, []); return ( <Command.Dialog open={open} onOpenChange={setOpen}> <Command.Input placeholder="输入命令或搜索…" /> <Command.List> <Command.Empty>无结果。</Command.Empty> <Command.Group heading="页面"> <Command.Item onSelect={() => go("/inbox")}>去收件箱 <kbd>⌘1</kbd></Command.Item> <Command.Item onSelect={() => go("/settings")}>去设置</Command.Item> </Command.Group> <Command.Group heading="动作"> <Command.Item onSelect={newDoc}>新文档 <kbd>⌘N</kbd></Command.Item> <Command.Item onSelect={toggleTheme}>切换主题</Command.Item> </Command.Group> </Command.List> </Command.Dialog> ); }

常见问题

  • ⚠无全局 Cmd+K — 面板仅从按钮开,高级用户无法随处触发
  • ⚠静态排序 — 同 50 命令同序,近度会浮其真用的 5
  • ⚠无快捷键提示 — 用户不发现 ⌘1 快捷键因藏设置中

最佳实践

  • ✓全局 Cmd+K 监听 — 随处开,非仅按钮聚焦时
  • ✓按近度 + 相关排 — 用户日跑的 5 命令应在顶
  • ✓内联显快捷键提示 — '新文档 ⌘N' 用面板时教快捷键

常见问题解答