Mention 提及
用于在输入中提及某人或某事。
基础用法
最简单的用法。
export function MentionBasic() { const [value, setValue] = useState("@"); return ( <ElMention value={value} onChange={setValue} options={BASIC_OPTIONS} style={mentionStyle} placeholder="Please input" /> );}
Props 2.11.3
你可以通过 props 属性自定义 options 的别名。
export function MentionProps() { const [value, setValue] = useState("@"); const options: MentionOption[] = [ { name: "Fuphoenixes", id: "Fuphoenixes", unable: true }, { name: "kooriookami", id: "kooriookami" }, { name: "Jeremy", id: "Jeremy", unable: true }, { name: "btea", id: "btea" }, ]; return ( <ElMention value={value} onChange={setValue} options={options} props={{ label: "name", value: "id", disabled: "unable" }} style={mentionStyle} placeholder="Please input" /> );}
Textarea
输入类型可以设置为 textarea 。
export function MentionTextarea() { const [value, setValue] = useState(""); return ( <ElMention value={value} onChange={setValue} type="textarea" options={BASIC_OPTIONS} style={mentionStyle} placeholder="Please input" /> );}
自定义标签
使用 "label" 自定义标签。
export function MentionLabel() { const [value, setValue] = useState(""); const options: MentionOption[] = [ { value: "Fuphoenixes", avatar: "https://avatars.githubusercontent.com/u/27912232" }, { value: "kooriookami", avatar: "https://avatars.githubusercontent.com/u/38392315" }, { value: "Jeremy", avatar: "https://avatars.githubusercontent.com/u/15975785" }, { value: "btea", avatar: "https://avatars.githubusercontent.com/u/24516654" }, ]; return ( <ElMention value={value} onChange={setValue} options={options} style={mentionStyle} placeholder="Please input" labelSlot={({ item }) => ( <div style={labelRowStyle}> <ElAvatar size={24} src={item.avatar as string} /> <span style={labelTextStyle}>{item.value}</span> </div> )} /> );}
加载远程选项
异步加载选项。
export function MentionLoading() { const [value, setValue] = useState(""); const [loading, setLoading] = useState(false); const [options, setOptions] = useState<MentionOption[]>([]); const timerRef = useRef<ReturnType<typeof setTimeout>>(undefined); useEffect(() => () => clearTimeout(timerRef.current), []); const handleSearch = (pattern: string) => { clearTimeout(timerRef.current); setLoading(true); timerRef.current = setTimeout(() => { setOptions( ["Fuphoenixes", "kooriookami", "Jeremy", "btea"].map((item) => ({ label: pattern + item, value: pattern + item, })), ); setLoading(false); }, 1500); }; return ( <ElMention value={value} onChange={setValue} options={options} loading={loading} onSearch={handleSearch} style={mentionStyle} placeholder="Please input" /> );}
自定义触发字段
通过 prefix 属性 自定义触发字段。默认为 @, Array<string> 。
export function MentionPrefix() { const [value, setValue] = useState(""); const [options, setOptions] = useState<MentionOption[]>([]); const handleSearch = (_pattern: string, prefix: string) => { setOptions((MOCK_DATA[prefix] || []).map((item) => ({ value: item }))); }; return ( <ElMention value={value} onChange={setValue} options={options} prefix={["@", "#"]} onSearch={handleSearch} style={mentionStyle} placeholder="input @ to mention people, # to mention tag" /> );}
整体删除
将whole属性设置为 true,当您按下退格键时,此处的 mention 区域将作为一个整体被删除。设置 "check-is-whole" 属性来自定义检查逻辑。
export function MentionWhole() { const [value1, setValue1] = useState(""); const [value2, setValue2] = useState(""); const [options2, setOptions2] = useState<MentionOption[]>([]); const options1: MentionOption[] = (MOCK_DATA["@"] || []).map((item) => ({ value: item, })); const handleSearch = (_pattern: string, prefix: string) => { setOptions2((MOCK_DATA[prefix] || []).map((item) => ({ value: item }))); }; const checkIsWhole = (pattern: string, prefix: string) => (MOCK_DATA[prefix] || []).includes(pattern); return ( <> <ElMention value={value1} onChange={setValue1} whole options={options1} style={mentionStyle} placeholder="Please input" /> <ElDivider /> <ElMention value={value2} onChange={setValue2} options={options2} prefix={["@", "#"]} whole checkIsWhole={checkIsWhole} onSearch={handleSearch} style={mentionStyle} placeholder="input @ to mention people, # to mention tag" /> </> );}
在表单里使用
与 el-form 一起使用
由于这个组件是基于el-input派生的,他们的原始属性未被更改,故不在此重复。请跳转查看原组件的相应文档。
export function MentionForm() { const formRef = useRef<FormExpose>(null); const [form, setForm] = useState({ name: "", desc: "" }); const patch = (patchValue: Partial<typeof form>) => setForm((prev) => ({ ...prev, ...patchValue })); const submit = async () => { try { const ok = await formRef.current!.validate(); console.log(ok ? "submit!" : "not valid"); } catch (fields) { console.log("error submit!", fields); } }; return ( <ElForm ref={formRef} model={form} rules={RULES} style={formStyle} onModelChange={(next) => setForm(next as typeof form)} > <ElFormItem label="name" prop="name"> <ElMention value={form.name} onChange={(v) => patch({ name: v })} options={BASIC_OPTIONS} /> </ElFormItem> <ElFormItem label="desc" prop="desc"> <ElMention value={form.desc} onChange={(v) => patch({ desc: v })} type="textarea" options={BASIC_OPTIONS} /> </ElFormItem> <ElFormItem> <ElButton type="primary" onClick={submit}>Submit</ElButton> <ElButton onClick={() => formRef.current?.resetFields()}>Reset</ElButton> </ElFormItem> </ElForm> );}
Mention API
Mention Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|
| value | 输入值 | string | — |
| options | 提及选项列表 | array | [] |
| props | 选项字段别名配置 | object | { value: 'value', label: 'label', disabled: 'disabled' } |
| prefix | 触发提及的前缀字符,长度必须为 1,可传数组 | string / array | '@' |
| split | 分隔提及的字符,长度必须为 1 | string | ' ' |
| filter-option | 自定义过滤逻辑,传 false 关闭过滤 | false / Function | 内置包含匹配 |
| placement | 弹出位置 | enum | 'bottom' |
| show-arrow | 弹层是否带箭头 | boolean | false |
| offset | 弹层偏移 | number | 0 |
| whole | 退格时是否把整个提及词作为一个整体删除 | boolean | false |
| check-is-whole | 自定义「整词」判定 | Function | — |
| loading | 下拉是否处于加载中 | boolean | false |
| popper-class | 弹层自定义类名 | string | — |
| popper-style | 弹层自定义样式 | object | — |
| popper-options | 透传给 popper.js 的配置 | object | — |
| input props | ElInput 的属性全部支持(size / placeholder / clearable / maxlength / type 等) | — | — |
Mention Events
| 事件名 | 说明 | 参数 |
|---|
| onChange | 输入值变化 | Function |
| onSearch | 命中前缀时触发 | Function |
| onSelect | 选中选项时触发 | Function |
| onWholeRemove | 整体删除提及词时触发 | Function |
| input events | ElInput 的事件全部支持 | — |
Mention Slots
React 里插槽以 render 函数形式的 props 提供。
| 名称 | 说明 | 类型 |
|---|
| labelSlot | 自定义选项内容 | Function |
| loadingSlot | 自定义加载内容 | ReactNode |
| headerSlot | 下拉顶部内容 | ReactNode |
| footerSlot | 下拉底部内容 | ReactNode |
| input slots | 通过 prefix / suffix / prepend / append / prefixIcon / suffixIcon 传入 | — |
Mention Exposes(ref)
| 名称 | 说明 | 类型 |
|---|
| input | 原生 input 元素,对应官方的 el-input 实例入口 | object |
| textarea | 原生 textarea 元素(type 为 textarea 时) | object |
| dropdownVisible | 下拉是否可见 | boolean(只读) |
MentionOption
| 字段 | 说明 | 类型 | 默认值 |
|---|
| value | 选项值 | string | — |
| label | 选项显示文本,省略时显示 value | string | — |
| disabled | 是否禁用该项 | boolean | false |
| [key: string] | 其它任意字段,供 labelSlot 使用 | any | — |