Навигация и горячие клавиши
Горячие клавиши
Модификатор + клавиша
// В определении команды (только для отображения — используйте perform() для действия)
{
id: 'save',
label: 'Save File',
shortcut: ['$mod', 's'],
perform: () => save(),
}Чтобы привязать настоящую глобальную горячую клавишу, используйте createKeyboardManager напрямую:
import { createKeyboardManager } from '@macrulez/vue-command-palette'
const km = createKeyboardManager()
km.start()
const unregister = km.registerShortcut(['$mod', 'shift', 'p'], () => {
openCommandPalette()
})
// Позже, для очистки:
unregister()
km.stop()Последовательности голых клавиш
Две последовательные клавиши без модификатора в пределах окна 500 мс:
km.registerShortcut(['g', 'h'], () => router.push('/home'))
km.registerShortcut(['g', 'p'], () => router.push('/projects'))
km.registerShortcut(['g', 's'], () => router.push('/settings'))Справочник по клавишам
| Строка | Разрешается в |
|---|---|
'$mod' | Meta на macOS, Ctrl на Windows/Linux |
'shift' | Shift |
'alt' | Alt / Option |
'ctrl' | Ctrl (явно, не кроссплатформенно) |
'meta' | Meta / Cmd (явно) |
| Любая другая строка | Сравнивается с event.key.toLowerCase() |
Привязка горячих клавиш
По умолчанию shortcut — это только визуальная подсказка. Установите bindShortcuts: true, и shortcut каждой команды станет настоящей глобальной горячей клавишей, запускающей команду через тот же поток, что и клик по ней (включая диалоги подтверждения и страницы). Горячие клавиши регистрируются и очищаются автоматически по мере добавления и удаления команд.
app.use(VCommandPalettePlugin, { bindShortcuts: true })
useRegisterCommands([
{ id: 'save', label: 'Save', shortcut: ['$mod', 's'], perform: () => save() },
{ id: 'find', label: 'Find', shortcut: ['$mod', 'f'], perform: () => openFind() },
])Вложенные палитры
Добавьте subCommands к любой команде, чтобы открывать дочернюю палитру при её выборе. Состояние родителя помещается в стек истории хлебных крошек.
{
id: 'change-theme',
label: 'Change Theme',
icon: '🎨',
perform: () => {}, // не вызывается, если присутствует subCommands
subCommands: [
{
id: 'theme-light',
label: 'Light',
icon: '☀️',
enabled: () => theme.value !== 'light',
perform: () => { theme.value = 'light' },
},
{
id: 'theme-dark',
label: 'Dark',
icon: '🌙',
enabled: () => theme.value !== 'dark',
perform: () => { theme.value = 'dark' },
},
{
id: 'theme-system',
label: 'System',
icon: '💻',
enabled: () => theme.value !== 'system',
perform: () => { theme.value = 'system' },
},
],
}Под-палитры можно вкладывать на любую глубину.
Вложенные команды доступны для поиска
По умолчанию (searchNested: true) ввод запроса также совпадает с командами внутри subCommands, поэтому поиск light покажет собственно команду Light, а не только её родителя Change Theme. Такие результаты показываются с контекстом хлебных крошек (Change Theme › Light) через SearchResult.parents, и выбор одного из них запускает его напрямую. Команды, открывающие под-палитру или страницу, показывают шеврон ›. Установите searchNested: false, чтобы ограничить поиск только командами верхнего уровня.
Клавиши навигации внутри под-палитры:
| Клавиша | Действие |
|---|---|
Backspace (пустой ввод) | Вернуться к родительской палитре |
Esc | Вернуться назад, если есть история, иначе закрыть |
Страницы команд
Команда может открыть страницу вместо (или в дополнение к) выполнения. Страница похожа на под-палитру, но со своим плейсхолдером и асинхронным обработчиком onSearch, управляемым вводом — идеально для удалённых пикеров и фильтров.
useRegisterCommands([
{
id: 'assign-user',
label: 'Assign to user…',
icon: '👤',
perform: () => {}, // не вызывается — вместо этого открывается страница
page: {
placeholder: 'Search users…',
// items: [...] // опциональные статичные элементы при пустом запросе
onSearch: async (query) => {
const users = await api.searchUsers(query)
return users.map((u) => ({
id: `user-${u.id}`,
label: u.name,
description: u.email,
perform: () => assign(u.id),
}))
},
},
},
])Backspace (пустой ввод) / Esc возвращают назад, точно как в под-палитрах. Результаты приходят с debounce 200 мс; если onSearch не задан, страница фильтрует свои статичные items по запросу.
Подтверждение
Установите confirm в непустую строку, чтобы требовать подтверждения пользователя перед выполнением команды.
{
id: 'delete-project',
label: 'Delete Project',
icon: '🗑️',
keywords: ['remove', 'erase'],
confirm: 'Delete this project permanently? This action cannot be undone.',
perform: async () => {
await api.deleteProject(projectId)
router.push('/')
},
}Палитра заменяет список результатов сообщением подтверждения и двумя кнопками:
- Да, продолжить — выполняет команду и закрывается
- Отмена — отклоняет и возвращает к списку результатов
Enter подтверждает, Esc отменяет.
История запросов
Недавно отправленные запросы запоминаются на время сессии. При пустом или любом другом вводе нажмите Alt+ArrowUp / Alt+ArrowDown, чтобы пройтись по предыдущим запросам (сначала самые недавние). Доступно только для чтения как useCommandPalette().queryHistory.