#Mention 提及
用于在文本输入时触发提及(@)候选列表的组件,支持自定义触发字符、匹配模式和渲染模板。
#组件特性
- 🛠️ 多匹配模式:支持前缀匹配(prefix)、完全匹配(exact)和模糊匹配(fuzzy)。
- ⌨️ 多触发字符:支持自定义单一或多个触发字符(如
@、#)。 - 🖱️ 高适应性:兼容普通输入框(Input)、文本域(Textarea)以及类富文本编辑器(ContentEditable)。
- 🎨 自定义渲染:支持通过插槽自定义提及候选列表项的展现形式。
#基础用法
最基础的提及展示,使用前缀匹配模式。
<script setup lang="ts">
import { ref } from 'vue'
const text = ref('')
const users = [
{ label: '张三', value: 'zhangsan' },
{ label: '李四', value: 'lisi' },
{ label: '王五', value: 'wangwu' },
{ label: '赵六', value: 'zhaoliu' }
]
const handleSelect = (opt: any) => {
// console.log('Selected:', opt.label)
}
</script>
<template>
<BrMention :options="users" @select="handleSelect">
<BrMentionTrigger>
<BrInput v-model="text" placeholder="输入 @ 提及用户" class="w-full" />
</BrMentionTrigger>
<BrMentionContent />
</BrMention>
</template>#模糊匹配与文本域
在文本域中使用模糊匹配,并设置最大高度。
<script setup lang="ts">
import { ref } from 'vue'
const text = ref('')
const projects = Array.from({ length: 30 }).map((_, i) => ({
label: `BreezeUI 项目 ${i + 1}`,
value: `project-${i + 1}`
}))
const handleSelect = (opt: any) => {
// console.log('Selected:', opt.label)
}
</script>
<template>
<BrMention
:options="projects"
match-mode="fuzzy"
max-height="200px"
@select="handleSelect"
>
<BrMentionTrigger>
<BrTextarea
v-model="text"
placeholder="输入 @ 提及项目 (支持模糊搜索,如输入 '1')"
:rows="4"
class="w-full"
/>
</BrMentionTrigger>
<BrMentionContent />
</BrMention>
</template>#自定义触发字符与列表项
支持多触发字符(@、# 等)以及自定义列表项的内容展示。
<script setup lang="ts">
import { ref } from 'vue'
const text = ref('')
const options = [
{ label: '前端开发部', value: 'fe', description: '负责BreezeUI组件库开发', avatar: 'https://avatars.githubusercontent.com/u/137638062?s=200&v=4' },
{ label: '设计部', value: 'design', description: '负责UI/UX设计规范', avatar: 'https://avatars.githubusercontent.com/u/137638062?s=200&v=4' },
{ label: '产品部', value: 'pm', description: '需求规划', disabled: true }
]
const handleSelect = (opt: any, trigger: string) => {
// console.log('Selected:', opt.label, 'Trigger:', trigger)
}
</script>
<template>
<BrMention :options="options" :trigger="['@', '#']" @select="handleSelect">
<BrMentionTrigger>
<BrInput v-model="text" placeholder="输入 @ 或 # 触发提及" class="w-full" />
</BrMentionTrigger>
<BrMentionContent>
<template #item="{ option, active }">
<div class="flex items-center gap-3 w-full p-2">
<div class="w-6 h-6 rounded-full overflow-hidden shrink-0">
<img v-if="option.avatar" :src="option.avatar" :alt="option.label" class="w-full h-full object-cover" />
</div>
<div class="flex flex-col flex-1">
<span :class="active ? 'text-primary font-medium' : ''">{{ option.label }}</span>
<span class="text-xs text-muted-foreground">{{ option.description }}</span>
</div>
<span v-if="option.disabled" class="text-xs text-destructive ml-auto">已禁用</span>
</div>
</template>
</BrMentionContent>
</BrMention>
</template>#ContentEditable 集成
在 contenteditable 元素中使用提及组件,这在富文本场景中非常常见。
<script setup lang="ts">
import { ref } from 'vue'
const users = [
{ label: '张三', value: 'zhangsan' },
{ label: '李四', value: 'lisi' },
{ label: '王五', value: 'wangwu' }
]
</script>
<template>
<BrMention :options="users">
<BrMentionTrigger>
<div
contenteditable="true"
class="min-h-[100px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
placeholder="在此处输入 @ 提及用户..."
></div>
</BrMentionTrigger>
<BrMentionContent />
</BrMention>
</template>#主题定制
结合 BrConfigProvider,可以全局覆盖组件默认样式,例如修改主题色和圆角,并配合 highlightClass 属性深度定制选中项的高亮样式。
<script setup lang="ts">
import { ref } from 'vue'
const text = ref('')
const users = [
{ label: '张三', value: 'zhangsan' },
{ label: '李四', value: 'lisi' },
{ label: '王五', value: 'wangwu' },
{ label: '赵六', value: 'zhaoliu' }
]
const handleSelect = (opt: any) => {
// console.log('Selected:', opt.label)
}
</script>
<template>
<BrConfigProvider :theme="{ primary: '280 84% 67%', radius: '1rem' }">
<div class="p-6 border rounded-2xl bg-card shadow-sm">
<BrMention
:options="users"
highlight-class="!bg-primary/20 !text-primary"
@select="handleSelect"
>
<BrMentionTrigger>
<BrInput v-model="text" placeholder="自定义主题色与高亮样式" class="w-full" />
</BrMentionTrigger>
<BrMentionContent class="shadow-xl border-primary" />
</BrMention>
</div>
</BrConfigProvider>
</template>#API 说明
#BrMention
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| trigger | string | string[] | '@' | 触发字符 |
| options | MentionOption[] | - | 候选列表数据 |
| matchMode | 'prefix' | 'exact' | 'fuzzy' | 'prefix' | 匹配模式 |
| position | 'auto' | 'top' | 'bottom' | 'left' | 'right' | 'auto' | 候选列表弹出的方向 |
| delay | number | 0 | 触发延迟时间(ms) |
| disabled | boolean | false | 是否禁用 |
| loading | boolean | false | 是否为加载中状态 |
| maxHeight | string | number | - | 候选列表最大高度 |
| isolated | boolean | false | 是否开启样式隔离 |
| showEmpty | boolean | true | 是否展示空状态 |
| highlightClass | string | - | 选中的高亮样式定制类名 |
#MentionOption 数据结构
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label | string | - | 选项显示的文本内容 |
| value | string | - | 选项的值 |
| disabled | boolean | false | 是否禁用该选项 |
| description | string | - | 额外描述文本 |
| avatar | string | - | 选项的头像地址 |
| [key: string] | any | - | 支持扩展自定义属性 |
#事件 (Emits)
| 事件名 | 参数 | 说明 |
|---|---|---|
| search | (query: string, trigger: string) | 搜索文本变化时触发 |
| select | (option: MentionOption, trigger: string) | 选中候选列表项时触发 |
| open-change | (open: boolean) | 候选列表展开/收起时触发 |
#插槽 (Slots)
#BrMentionContent
| 插槽名 | 参数 | 说明 |
|---|---|---|
| item | { option: MentionOption, active: boolean } | 自定义候选列表项渲染 |