Command 命令面板
命令面板(⌘K 唤起,快捷键可配置)——搜索过滤、匹配打分排序、键盘选择、Enter 执行、嵌套子页导航、最近使用、多选批量执行。open 受控:可由外部设置,也可用全局快捷键或 Esc 关闭(打开/关闭各派发一次 oas-open-change)。
基础用法
基础用法(⌘J / Ctrl+J 打开)
受控打开
open 属性由外部控制:外部按钮设置 open 打开面板;关闭由 Esc / 点击遮罩 / 选择命令触发(组件移除 open,受控关闭由宿主监听 oas-open-change 同步状态)。
打开时遮罩铺满全屏,因此「关闭」不提供外部按钮,用 Esc / 点击遮罩 / 选择命令关闭。
外部控制 open(oas-open-change 同步)
分组与空态
分组标题按 group 字段渲染;无匹配时显示空态(空查询显示「无匹配命令」,有搜索词时显示「未找到与「词」匹配的命令」)。
分组与空态
图标 · 副标题 · 快捷键标注
项级字段 icon(SVG path d 或完整 <svg> 标记)、description(副标题)、shortcut(右对齐 kbd,支持 meta/ctrl/shift/alt 符号映射)。
图标 + 副标题 + 快捷键
唤起快捷键配置
hotkey 属性可配置组合键(mod/meta/ctrl/alt/shift,逗号分隔多组);false 关闭内置监听。默认 mod+k(⌘K / Ctrl+K)。
自定义快捷键(ctrl+shift+p)与禁用
匹配高亮
搜索时 label 中命中搜索词的字符以 <mark> 高亮,输入即反馈。
搜索高亮
外部过滤(should-filter=false)
should-filter="false" 关闭内置过滤与打分,过滤完全交给宿主:输入时组件派发 oas-input,宿主请求异步数据源后回写 items。本 demo 模拟 600ms 服务端搜索;无结果时返回一条 forceMount 的「创建」入口(忽略过滤强制显示)。
should-filter=false + 异步数据源
空态插槽
slot="empty" 自定义空结果渲染(替代默认「未找到…」文案);宿主用 el.query 读当前搜索词。示例:无结果时展示「创建 xxx」按钮。
空结果插槽
嵌套页面 / 面包屑回退
项级字段 page(命令数组)定义子页:选中进入子页(顶部出现面包屑 + 返回按钮),Esc 或空搜索词 Backspace 回退,根层 Esc 才关闭面板。进出子页各派发一次 oas-page-change。
嵌套页面
子元素声明式通道
除 items JSON 外,可用 <oas-command-item> 子元素声明式书写命令(items 属性显式设置时优先,未设置时解析子元素收敛到同一渲染路径)。默认插槽文本为 label,属性对齐 items 字段:value / group / disabled / icon / shortcut / description / view / force-mount / separator;keywords 为逗号分隔字符串参与搜索匹配。<oas-command-item> 内直接嵌套子元素即递归为 page 子页。子元素增删、属性与文本变化会自动重渲染(MutationObserver)。
子元素声明式(分组 / separator / shortcut / 嵌套子页)
最近使用
recent 开启最近使用:选中项按最近优先置顶(去重,上限 10 条);recent-storage-key 启用 localStorage 持久化(跨实例恢复)。本 demo 选中后模拟「命令集变化」切换 items,重开可见「最近使用」组。
最近使用(localStorage 持久化)
loading 与 limit
loading 显示异步加载占位(列表含 spinner + aria-busy);limit 限制渲染条数(默认 50)。
loading 与 limit
多选命令
multiple 多选模式:Enter/点击切换勾选(派发 oas-change { values }),footer 出现「执行 n 项」确认按钮批量执行(派发 oas-select { values })。
多选批量执行
面板内嵌视图(Raycast 风格)
项级字段 view 定义视图:选中进入 <slot name="view-{view}"> 承载的表单/面板(如部署参数、快速操作),Esc/面包屑回退。进出各派发一次 oas-view-change。
视图插槽(部署表单)
受控搜索词与选中项
value 受控搜索词(宿主监听 oas-input 回写实现双向);selected 受控当前项(宿主监听 oas-active 回写)。close-on-select="false" 选中后不关闭,可连续执行。
受控 value / selected
底部自定义
slot="footer" 替换默认快捷键提示条(↑↓ 选择 / ↵ 执行 / esc 关闭)。
footer 插槽
挂载容器
append-to:整个面板(遮罩 + 面板)移入指定容器的 portal host(独立 shadow + 样式注入 + 插槽桥接,empty/footer/view-* 插槽内容随面板迁移),适合嵌套 transform / stacking context 场景。
append-to 挂载容器
虚拟滚动
virtual 开启虚拟滚动(大数据量窗口渲染,复用 oas-virtual-list;有分组/最近项时自动回退全量渲染)。本 demo 预置 20000 条命令,只渲染可见窗口。
虚拟滚动(2 万项)
API
oas-command
属性
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
append-to | 挂载容器选择器(如 #panel):整个面板(遮罩 + 面板)移入目标容器的 portal host(独立 shadow + 样式注入 + 插槽桥接,empty/footer/view-* 插槽随面板迁移),适合嵌套 transform/stacking context 场景;未设置时面板在组件自身 shadow 内 fixed 定位 | string | — |
close-on-select | 选中后是否关闭面板(默认 true;false 支持连续执行) | string | — |
hotkey | 唤起快捷键组合,如 ctrl+k / meta+shift+p(逗号分隔多组,支持 mod/meta/ctrl/alt/shift);false 关闭内置监听(默认 mod+k) | string | mod+k |
item-height | 虚拟滚动行高(默认 36) | string | 36 |
items | 命令项 JSON(根页;子页由 item.page 提供,含 icon / shortcut / description / page / view / forceMount / separator 字段) | CommandItem[] | string | [] |
limit | 渲染条数上限(默认 50;虚拟滚动不受限) | string | 50 |
loading | 异步加载占位态(列表显示加载行 + aria-busy) | boolean | — |
multiple | 多选命令模式(勾选切换 + footer 批量执行) | boolean | — |
open | 是否打开(受控;选择 / Esc 后自动移除,打开/关闭各派发一次 oas-open-change) | boolean | — |
recent | 记录最近使用(选中项按最近优先置顶,去重,上限 10 条) | boolean | — |
recent-storage-key | 最近使用 localStorage 持久化键(需配合 recent;跨实例恢复) | string | — |
selected | 当前高亮项 value(受控;方向键/悬停派发 oas-active,宿主回写生效) | string | — |
should-filter | false 关闭内置过滤与打分排序(过滤交给宿主,接异步/服务端数据源) | string | true |
value | 搜索词(受控;宿主监听 oas-input 回写实现双向) | string | — |
virtual | 虚拟滚动(大数据量窗口渲染,复用 oas-virtual-list) | boolean | — |
事件
| 事件 | 说明 |
|---|---|
oas-active | 高亮项变化,detail: { value }(受控 selected 的回写依据) |
oas-change | 多选勾选变化,detail: { values } |
oas-input | 搜索词输入,detail: { value }(should-filter=false 外部过滤的请求通道) |
oas-open-change | 面板打开/关闭,detail: { open } |
oas-page-change | 子页推入/回退,detail: { title, depth, direction }(direction: push|pop) |
oas-select | 执行某项,detail: { value };多选确认 detail: { values } |
oas-view-change | 视图进出,detail: { view, title }(退出时 view: '') |
插槽
| 名称 | 说明 |
|---|---|
empty | 空结果自定义渲染(组件内用 el.query 读当前搜索词,如「创建 xyz」入口) |
footer | 底部自定义条(默认显示 ↑↓ 选择 / ↵ 执行 / esc 关闭 提示) |
view-${view} | 按视图名覆盖该视图的选中内容(宿主写 <div slot="view-deploy"> …,view 为视图字段的值) |
oas-command-item
属性
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
description | 副标题(description) | — | — |
disabled | 禁用该项(Enter/点击不可选,方向键跳过) | — | — |
force-mount | 忽略过滤强制显示(创建型入口) | — | — |
group | 分组名(可选),同组项渲染分组标题 | — | — |
icon | 项图标:SVG path d 字符串或完整 <svg> 标记 | — | — |
keywords | 搜索关键词(逗号分隔字符串,trim 去空后解析为 string[]),参与 label 之外的匹配 | — | — |
separator | 渲染为分隔行(不可导航/不可选中) | — | — |
shortcut | 快捷键标注(右对齐 kbd),如 meta+p / ctrl+shift+s | — | — |
value | 选中值(子元素声明式通道的数据载体字段) | — | — |
view | 视图插槽名:选中进入 <slot name="view-{view}">(面板内嵌视图) | — | — |
插槽
| 名称 | 说明 |
|---|---|
| 默认 | 命令项 label 内容(默认插槽文本);直接子元素 <oas-command-item> 递归为 page 子页 |
CommandItem 字段:
| 字段 | 说明 | 类型 |
|---|---|---|
label | 显示文案 | string |
value | 选中值(oas-select detail.value) | string |
keywords | 搜索关键词(可选),参与 label 之外的匹配 | string[] |
group | 分组名(可选),同组项渲染分组标题 | string |
disabled | 禁用该项(Enter/点击不可选,方向键跳过) | boolean |
icon | 项图标(SVG path d 字符串或完整 <svg> 标记,宿主数据视为可信内容) | string |
shortcut | 快捷键标注(右对齐 kbd 展示),如 "meta+p" / "ctrl+shift+s" | string |
description | 副标题描述文本 | string |
page | 子页命令(嵌套页面):选中进入子页,Esc / 空搜索词 Backspace 回退 | CommandItem[] |
view | 视图插槽名:选中进入 <slot name="view-{view}">(面板内嵌视图) | string |
forceMount | 忽略过滤强制显示(创建型入口) | boolean |
separator | 渲染为分隔行(不可导航/不可选中) | boolean |
键盘:↑/↓ 移动高亮(跳过 disabled),Enter 执行并关闭(多选模式切换勾选),Esc 关闭(有子页时先回退子页),空搜索词 Backspace 回退子页,Tab 在搜索框与选项间循环(焦点陷阱);打开时自动聚焦搜索框,关闭后焦点归还来源元素。全局快捷键默认 ⌘K / Ctrl+K(hotkey 可配置或关闭)。