Command 命令菜单

快速、可组合的 Vue 命令菜单。

组件特性

  • 快速响应:基于 Radix Vue 构建,提供极致的交互性能。
  • 🧩 高度可组合:由多个小组件组合而成,灵活适配各种业务场景。
  • 🎨 无样式设计:默认提供基础骨架,通过 Tailwind CSS 轻松定制外观。
  • ⌨️ 键盘导航:完全支持无障碍访问,提供顺滑的键盘操作体验。
  • 📋 嵌套支持:支持子命令和层级导航,轻松构建复杂的命令树。

基础用法

<script setup lang="ts">
import {
  BrCommand,
  BrCommandEmpty,
  BrCommandGroup,
  BrCommandInput,
  BrCommandItem,
  BrCommandList,
  BrCommandSeparator,
  BrCommandShortcut,
} from '@breezeui/vue'
</script>

<template>
  <BrCommand class="rounded-lg border shadow-md max-w-[450px]">
    <BrCommandInput placeholder="Type a command or search..." />
    <BrCommandList>
      <BrCommandEmpty>No results found.</BrCommandEmpty>
      <BrCommandGroup heading="Suggestions">
        <BrCommandItem value="calendar">
          Calendar
        </BrCommandItem>
        <BrCommandItem value="search-emoji">
          Search Emoji
        </BrCommandItem>
        <BrCommandItem value="calculator">
          Calculator
        </BrCommandItem>
      </BrCommandGroup>
      <BrCommandSeparator />
      <BrCommandGroup heading="Settings">
        <BrCommandItem value="profile">
          Profile
          <BrCommandShortcut>⌘P</BrCommandShortcut>
        </BrCommandItem>
        <BrCommandItem value="billing">
          Billing
          <BrCommandShortcut>⌘B</BrCommandShortcut>
        </BrCommandItem>
        <BrCommandItem value="settings">
          Settings
          <BrCommandShortcut>⌘S</BrCommandShortcut>
        </BrCommandItem>
      </BrCommandGroup>
    </BrCommandList>
  </BrCommand>
</template>

弹窗模式

你可以使用 BrCommandDialog 组件在对话框中渲染命令菜单。

<script setup lang="ts">
import { ref } from 'vue'
import {
  BrButton,
  BrCommandDialog,
  BrCommandEmpty,
  BrCommandGroup,
  BrCommandInput,
  BrCommandItem,
  BrCommandList,
  BrCommandSeparator,
  BrCommandShortcut,
} from '@breezeui/vue'

const open = ref(false)

// Optional: Add keyboard shortcut to open the command dialog
// import { onMounted, onUnmounted } from 'vue'
// onMounted(() => {
//   const down = (e: KeyboardEvent) => {
//     if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
//       e.preventDefault()
//       open.value = !open.value
//     }
//   }
//   document.addEventListener('keydown', down)
//   onUnmounted(() => document.removeEventListener('keydown', down))
// })
</script>

<template>
  <div>
    <p class="text-sm text-muted-foreground mb-4">
      Press <kbd class="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"><span class="text-xs">⌘</span>K</kbd> or click the button below.
    </p>
    
    <BrButton variant="outline" @click="open = true">
      Open Command Dialog
    </BrButton>

    <BrCommandDialog v-model:open="open">
      <BrCommandInput placeholder="Type a command or search..." />
      <BrCommandList>
        <BrCommandEmpty>No results found.</BrCommandEmpty>
        <BrCommandGroup heading="Suggestions">
          <BrCommandItem value="calendar">
            Calendar
          </BrCommandItem>
          <BrCommandItem value="search-emoji">
            Search Emoji
          </BrCommandItem>
          <BrCommandItem value="calculator">
            Calculator
          </BrCommandItem>
        </BrCommandGroup>
        <BrCommandSeparator />
        <BrCommandGroup heading="Settings">
          <BrCommandItem value="profile">
            Profile
            <BrCommandShortcut>⌘P</BrCommandShortcut>
          </BrCommandItem>
          <BrCommandItem value="billing">
            Billing
            <BrCommandShortcut>⌘B</BrCommandShortcut>
          </BrCommandItem>
          <BrCommandItem value="settings">
            Settings
            <BrCommandShortcut>⌘S</BrCommandShortcut>
          </BrCommandItem>
        </BrCommandGroup>
      </BrCommandList>
    </BrCommandDialog>
  </div>
</template>

嵌套子命令

你可以通过切换活动页面在不同的命令组之间进行导航。

<script setup lang="ts">
import { ref } from 'vue'
import {
  BrCommand,
  BrCommandEmpty,
  BrCommandGroup,
  BrCommandInput,
  BrCommandItem,
  BrCommandList,
  BrCommandSeparator,
} from '@breezeui/vue'

const activePage = ref('home')
</script>

<template>
  <BrCommand class="rounded-lg border shadow-md max-w-[450px]">
    <BrCommandInput placeholder="Type a command or search..." />
    <BrCommandList>
      <BrCommandEmpty>No results found.</BrCommandEmpty>
      
      <template v-if="activePage === 'home'">
        <BrCommandGroup heading="Suggestions">
          <BrCommandItem value="search-projects" @select="activePage = 'projects'">
            Search Projects...
          </BrCommandItem>
          <BrCommandItem value="search-users" @select="activePage = 'users'">
            Search Users...
          </BrCommandItem>
        </BrCommandGroup>
        <BrCommandSeparator />
        <BrCommandGroup heading="Settings">
          <BrCommandItem value="profile">
            Profile
          </BrCommandItem>
        </BrCommandGroup>
      </template>

      <template v-else-if="activePage === 'projects'">
        <BrCommandItem value="back" @select="activePage = 'home'">
          ← Back
        </BrCommandItem>
        <BrCommandGroup heading="Projects">
          <BrCommandItem value="breeze-ui">
            Breeze UI
          </BrCommandItem>
          <BrCommandItem value="vue-app">
            Vue App
          </BrCommandItem>
        </BrCommandGroup>
      </template>

      <template v-else-if="activePage === 'users'">
        <BrCommandItem value="back" @select="activePage = 'home'">
          ← Back
        </BrCommandItem>
        <BrCommandGroup heading="Users">
          <BrCommandItem value="admin">
            Admin
          </BrCommandItem>
          <BrCommandItem value="guest">
            Guest
          </BrCommandItem>
        </BrCommandGroup>
      </template>
    </BrCommandList>
  </BrCommand>
</template>

全局快捷唤起

你可以绑定全局键盘快捷键来打开命令弹窗。

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import {
  BrCommandDialog,
  BrCommandEmpty,
  BrCommandGroup,
  BrCommandInput,
  BrCommandItem,
  BrCommandList,
  BrCommandSeparator,
  BrCommandShortcut,
} from '@breezeui/vue'

const open = ref(false)

const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
    e.preventDefault()
    open.value = !open.value
  }
}

onMounted(() => {
  document.addEventListener('keydown', handleKeyDown)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeyDown)
})
</script>

<template>
  <div>
    <p class="text-sm text-muted-foreground mb-4">
      Press <kbd class="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"><span class="text-xs">⌘</span>K</kbd> to open the command dialog.
    </p>

    <BrCommandDialog v-model:open="open">
      <BrCommandInput placeholder="Type a command or search..." />
      <BrCommandList>
        <BrCommandEmpty>No results found.</BrCommandEmpty>
        <BrCommandGroup heading="Suggestions">
          <BrCommandItem value="calendar">
            Calendar
          </BrCommandItem>
          <BrCommandItem value="search-emoji">
            Search Emoji
          </BrCommandItem>
          <BrCommandItem value="calculator">
            Calculator
          </BrCommandItem>
        </BrCommandGroup>
        <BrCommandSeparator />
        <BrCommandGroup heading="Settings">
          <BrCommandItem value="profile">
            Profile
            <BrCommandShortcut>⌘P</BrCommandShortcut>
          </BrCommandItem>
          <BrCommandItem value="billing">
            Billing
            <BrCommandShortcut>⌘B</BrCommandShortcut>
          </BrCommandItem>
          <BrCommandItem value="settings">
            Settings
            <BrCommandShortcut>⌘S</BrCommandShortcut>
          </BrCommandItem>
        </BrCommandGroup>
      </BrCommandList>
    </BrCommandDialog>
  </div>
</template>

API

Command Props

名称类型默认值说明
openbooleantrue命令菜单的打开状态
modelValuestring''选中项的值
filterFunction(val: any[], search: string) => any[]-自定义过滤函数

CommandInput Props

名称类型默认值说明
valuestring''搜索值

CommandItem Props

名称类型默认值说明
valuestring-选项的值
disabledbooleanfalse是否禁用该选项

CommandGroup Props

名称类型默认值说明
headingstring-分组标题

CommandDialog Props

名称类型默认值说明
openbooleanfalse弹窗的打开状态