Интеграции и тестирование
Множественные инстансы
Запускайте несколько независимых палитр в одном приложении — например, глобальную командную строку плюс поиск в сайдбаре — каждую со своей горячей клавишей, командами и состоянием. Используйте createCommandPalette() для каждого инстанса, кроме дефолтного (она возвращает новый объект плагина, чтобы дедупликация app.use во Vue его не пропустила).
import { VCommandPalettePlugin, createCommandPalette } from '@macrulez/vue-command-palette'
app.use(VCommandPalettePlugin) // инстанс по умолчанию
app.use(createCommandPalette({ name: 'sidebar', hotkey: ['$mod', 'j'] }))<template>
<!-- по умолчанию -->
<CommandPalette />
<!-- sidebar -->
<CommandPalette name="sidebar" placeholder="Search the sidebar…" />
</template>Обращайтесь к конкретному инстансу из composables через аргумент name:
const sidebar = useCommandPalette('sidebar')
useRegisterCommands([/* … */], 'sidebar')
useRegisterGroup({/* … */}, 'sidebar')Nuxt
Добавьте в nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@macrulez/vue-command-palette/nuxt'],
})Опции читаются из runtimeConfig.public.vCommandPalette. Настройте в nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@macrulez/vue-command-palette/nuxt'],
runtimeConfig: {
public: {
vCommandPalette: {
hotkey: ['$mod', 'k'],
persistRecent: true,
maxRecent: 5,
},
},
},
})Модуль Nuxt устанавливает плагин автоматически. useCommandPalette, useRegisterGroup и useRegisterCommands доступны во всех компонентах без явных импортов (при использовании @nuxt/eslint с включёнными автоимпортами).
Утилиты для тестирования
import { createPaletteContext, PaletteProvider } from '@macrulez/vue-command-palette/testing'createPaletteContext
Создаёт полностью изолированный контекст палитры — без реального DOM, без плагина, без побочных эффектов localStorage:
import { createPaletteContext } from '@macrulez/vue-command-palette/testing'
import { mount } from '@vue/test-utils'
import { describe, it, expect, vi } from 'vitest'
import MyComponent from './MyComponent.vue'
describe('MyComponent', () => {
it('executes the command', async () => {
const performFn = vi.fn()
const { provide, isOpen, query, store } = createPaletteContext({
commands: [{ id: 'test-cmd', label: 'Test Command', perform: performFn }],
})
const wrapper = mount(MyComponent, {
global: { provide },
})
// Взаимодействие
query.value = 'test'
await wrapper.find('[data-testid="item"]').trigger('click')
expect(performFn).toHaveBeenCalledOnce()
})
})PaletteProvider
Компонент-обёртка, предоставляющий контекст своим дочерним элементам слота — полезен для тестов дерева компонентов:
import { PaletteProvider } from '@macrulez/vue-command-palette/testing'
import { mount } from '@vue/test-utils'
const wrapper = mount(PaletteProvider, {
props: {
commands: [{ id: 'cmd', label: 'My Command', perform: vi.fn() }],
groups: [],
},
slots: {
default: MyConsumerComponent,
},
})Опции createPaletteContext
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
commands | Command[] | [] | Команды для предварительной регистрации (без группы) |
groups | CommandGroup[] | [] | Группы для предварительной регистрации |
persistRecent | boolean | false | Включить персистентность в localStorage |
maxRecent | number | 5 | Лимит недавних команд |
maxRecentPerGroup | number | 0 | Лимит недавних на группу |
localStorageKey | string | 'vcp:recent:test' | Ключ, если persistRecent равен true |
onOpen | () => void | — | Мок-колбэк для событий открытия |
onClose | () => void | — | Мок-колбэк для событий закрытия |
onError | (err, cmd) => void | — | Мок-обработчик ошибок |
Возвращаемое значение
const {
ctx, // полный PaletteContext — передавайте в код на основе inject
store, // CommandStore — регистрируйте/ищите команды напрямую
isOpen, // Ref<boolean>
query, // Ref<string>
activeIndex, // Ref<number>
provide, // объект для Vue Test Utils `global: { provide }`
} = createPaletteContext(options)