mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat: add mention component (#17586)
* feat: add mention component * fix: build error * fix: build error * feat: delete as a whole * fix: update docs * fix: update global.d.ts * fix: update * fix: update code * fix: update code * fix: update code * fix: rename * fix: update code * fix: upload code * fix: update code * fix: fixed cursor position abnormality * fix: update code * fix: docs add avatar * fix: tooltip position is wrong when placing on top * feat: add overview icon * fix: overview icon color
This commit is contained in:
@@ -106,6 +106,11 @@
|
||||
"link": "/input-number",
|
||||
"text": "Input Number"
|
||||
},
|
||||
{
|
||||
"link": "/mention",
|
||||
"text": "Mention",
|
||||
"promotion": "2.8.0"
|
||||
},
|
||||
{
|
||||
"link": "/radio",
|
||||
"text": "Radio"
|
||||
|
||||
@@ -71,6 +71,7 @@ import OvPopover from './ov-popover.vue'
|
||||
import OvTooltip from './ov-tooltip.vue'
|
||||
import OvDivider from './ov-divider.vue'
|
||||
import OvWatermark from './ov-watermark.vue'
|
||||
import OvMention from './ov-mention.vue'
|
||||
|
||||
export default {
|
||||
button: OvButton,
|
||||
@@ -149,4 +150,5 @@ export default {
|
||||
tooltip: OvTooltip,
|
||||
divider: OvDivider,
|
||||
watermark: OvWatermark,
|
||||
mention: OvMention,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<svg
|
||||
width="280"
|
||||
height="180"
|
||||
viewBox="0 0 280 180"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect width="280" height="180" fill="var(--el-fill-color-light)" />
|
||||
<rect
|
||||
x="85.5"
|
||||
y="40.5"
|
||||
width="99"
|
||||
height="19"
|
||||
rx="1.5"
|
||||
fill="var(--el-fill-color-blank)"
|
||||
stroke="var(--el-color-primary)"
|
||||
/>
|
||||
<g filter="url(#filter0_d_1544_8231)">
|
||||
<rect
|
||||
x="85"
|
||||
y="62"
|
||||
width="100"
|
||||
height="68"
|
||||
rx="2"
|
||||
fill="var(--el-bg-color-overlay)"
|
||||
/>
|
||||
<rect
|
||||
x="84.7"
|
||||
y="61.7"
|
||||
width="100.6"
|
||||
height="68.6"
|
||||
rx="2.3"
|
||||
stroke="var(--el-border-color-dark)"
|
||||
stroke-width="0.6"
|
||||
/>
|
||||
</g>
|
||||
<rect
|
||||
x="93"
|
||||
y="74"
|
||||
width="25"
|
||||
height="4"
|
||||
rx="2"
|
||||
fill="var(--el-border-color-dark)"
|
||||
/>
|
||||
<path
|
||||
d="M93.47 46.72C94.55 46.72 95.4 47.0433 96.02 47.69C96.5533 48.2567 96.82 48.9467 96.82 49.76C96.82 50.4533 96.5967 51.1033 96.15 51.71C95.6967 52.3033 95.1833 52.6 94.61 52.6C94.1967 52.6 93.9533 52.3933 93.88 51.98C93.5933 52.4 93.2067 52.61 92.72 52.61C92.2733 52.61 91.91 52.46 91.63 52.16C91.35 51.86 91.21 51.4833 91.21 51.03C91.21 50.33 91.4267 49.7133 91.86 49.18C92.2867 48.6333 92.8033 48.36 93.41 48.36C93.8367 48.36 94.14 48.59 94.32 49.05L94.46 48.55H95.35L94.67 50.99C94.57 51.35 94.52 51.5733 94.52 51.66C94.52 51.7933 94.5933 51.86 94.74 51.86C95.0133 51.86 95.2933 51.6767 95.58 51.31C95.9 50.89 96.06 50.3767 96.06 49.77C96.06 49.15 95.84 48.6233 95.4 48.19C94.92 47.7167 94.2567 47.48 93.41 47.48C92.5167 47.48 91.8 47.7633 91.26 48.33C90.7267 48.8833 90.46 49.61 90.46 50.51C90.46 51.4967 90.7433 52.24 91.31 52.74C91.83 53.2 92.5767 53.43 93.55 53.43C94.1833 53.43 94.7367 53.3267 95.21 53.12C95.63 52.92 95.9667 52.6433 96.22 52.29H97.16C96.8067 52.9233 96.29 53.4 95.61 53.72C94.99 54 94.3033 54.14 93.55 54.14C92.2633 54.14 91.2667 53.81 90.56 53.15C89.8533 52.49 89.5 51.5967 89.5 50.47C89.5 49.4233 89.8433 48.5533 90.53 47.86C91.27 47.1 92.25 46.72 93.47 46.72ZM93.59 49.23C93.21 49.23 92.88 49.42 92.6 49.8C92.32 50.18 92.18 50.6033 92.18 51.07C92.18 51.31 92.23 51.49 92.33 51.61C92.43 51.7433 92.5867 51.81 92.8 51.81C92.9933 51.81 93.18 51.74 93.36 51.6C93.56 51.44 93.7 51.2333 93.78 50.98L93.98 50.26C94.06 49.9733 94.1 49.7967 94.1 49.73C94.1 49.5833 94.0467 49.4633 93.94 49.37C93.8467 49.2767 93.73 49.23 93.59 49.23Z"
|
||||
fill="var(--el-color-primary)"
|
||||
/>
|
||||
<rect
|
||||
x="93"
|
||||
y="94"
|
||||
width="25"
|
||||
height="4"
|
||||
rx="2"
|
||||
fill="var(--el-color-primary)"
|
||||
/>
|
||||
<rect
|
||||
x="93"
|
||||
y="114"
|
||||
width="25"
|
||||
height="4"
|
||||
rx="2"
|
||||
fill="var(--el-border-color-dark)"
|
||||
/>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_d_1544_8231"
|
||||
x="81"
|
||||
y="59"
|
||||
width="108"
|
||||
height="76"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dy="1" />
|
||||
<feGaussianBlur stdDeviation="2" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_1544_8231"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_1544_8231"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</template>
|
||||
1
docs/components.d.ts
vendored
1
docs/components.d.ts
vendored
@@ -82,6 +82,7 @@ declare module 'vue' {
|
||||
OvLayout: typeof import('./.vitepress/vitepress/components/overview-icons/ov-layout.vue')['default']
|
||||
OvLink: typeof import('./.vitepress/vitepress/components/overview-icons/ov-link.vue')['default']
|
||||
OvLoading: typeof import('./.vitepress/vitepress/components/overview-icons/ov-loading.vue')['default']
|
||||
OvMention: typeof import('./.vitepress/vitepress/components/overview-icons/ov-mention.vue')['default']
|
||||
OvMenu: typeof import('./.vitepress/vitepress/components/overview-icons/ov-menu.vue')['default']
|
||||
OvMessage: typeof import('./.vitepress/vitepress/components/overview-icons/ov-message.vue')['default']
|
||||
OvMessageBox: typeof import('./.vitepress/vitepress/components/overview-icons/ov-message-box.vue')['default']
|
||||
|
||||
@@ -173,17 +173,18 @@ input/length-limiting
|
||||
|
||||
### Exposes
|
||||
|
||||
| Name | Description | Type |
|
||||
| -------------- | -------------------------------- | ------------------------------------------------------- |
|
||||
| blur | blur the input element | ^[Function]`() => void` |
|
||||
| clear | clear input value | ^[Function]`() => void` |
|
||||
| focus | focus the input element | ^[Function]`() => void` |
|
||||
| input | HTML input element | ^[object]`Ref<HTMLInputElement>` |
|
||||
| ref | HTML element, input or textarea | ^[object]`Ref<HTMLInputElement \| HTMLTextAreaElement>` |
|
||||
| resizeTextarea | resize textarea | ^[Function]`() => void` |
|
||||
| select | select the text in input element | ^[Function]`() => void` |
|
||||
| textarea | HTML textarea element | ^[object]`Ref<HTMLTextAreaElement>` |
|
||||
| textareaStyle | style of textarea | ^[object]`Ref<StyleValue>` |
|
||||
| Name | Description | Type |
|
||||
| -------------------- | -------------------------------- | ------------------------------------------------------- |
|
||||
| blur | blur the input element | ^[Function]`() => void` |
|
||||
| clear | clear input value | ^[Function]`() => void` |
|
||||
| focus | focus the input element | ^[Function]`() => void` |
|
||||
| input | HTML input element | ^[object]`Ref<HTMLInputElement>` |
|
||||
| ref | HTML element, input or textarea | ^[object]`Ref<HTMLInputElement \| HTMLTextAreaElement>` |
|
||||
| resizeTextarea | resize textarea | ^[Function]`() => void` |
|
||||
| select | select the text in input element | ^[Function]`() => void` |
|
||||
| textarea | HTML textarea element | ^[object]`Ref<HTMLTextAreaElement>` |
|
||||
| textareaStyle | style of textarea | ^[object]`Ref<StyleValue>` |
|
||||
| isComposing ^(2.8.0) | is input composing | ^[object]`Ref<boolean>` |
|
||||
|
||||
## FAQ
|
||||
|
||||
|
||||
145
docs/en-US/component/mention.md
Normal file
145
docs/en-US/component/mention.md
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
title: Mention
|
||||
lang: en-US
|
||||
---
|
||||
|
||||
# Mention
|
||||
|
||||
Used to mention someone or something in an input.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
The most basic usage.
|
||||
|
||||
:::demo
|
||||
|
||||
mention/basic
|
||||
|
||||
:::
|
||||
|
||||
## Textarea
|
||||
|
||||
The input type can be set to `textarea`.
|
||||
|
||||
:::demo
|
||||
|
||||
mention/textarea
|
||||
|
||||
:::
|
||||
|
||||
## Customize label
|
||||
|
||||
Customize label by `label` slot.
|
||||
|
||||
:::demo
|
||||
|
||||
mention/label
|
||||
|
||||
:::
|
||||
|
||||
## Load remote options
|
||||
|
||||
Load options asynchronously.
|
||||
|
||||
:::demo
|
||||
|
||||
mention/loading
|
||||
|
||||
:::
|
||||
|
||||
## Customize trigger token
|
||||
|
||||
Customize trigger token by `prefix` props. Default to `@`, `Array<string>` also supported.
|
||||
|
||||
:::demo
|
||||
|
||||
mention/prefix
|
||||
|
||||
:::
|
||||
|
||||
## Delete as a whole
|
||||
|
||||
Set the `whole` attribute to `true`, and when you press the backspace, the mention will be deleted as a whole.
|
||||
Set the `check-is-whole` attribute to customize the checking logic.
|
||||
:::demo
|
||||
|
||||
mention/whole
|
||||
|
||||
:::
|
||||
|
||||
## Work with form
|
||||
|
||||
to work with `el-form`.
|
||||
|
||||
:::demo
|
||||
|
||||
mention/form
|
||||
|
||||
:::
|
||||
|
||||
::: tip
|
||||
Since this component is developed based on the component [`el-input`](./input.md#attributes) , the original properties have not changed, so no repetition here,
|
||||
and please go to the original component to view the documentation.
|
||||
:::
|
||||
|
||||
## API
|
||||
|
||||
### Attributes
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| ------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------- |
|
||||
| options | mention options list | ^[array]`MentionOption[]` | [] |
|
||||
| prefix | prefix character to trigger mentions. The string length must be exactly 1 | ^[string] \| ^[array]`string[]` | `'@'` |
|
||||
| split | character to split mentions. The string length must be exactly 1 | ^[string] | `' '` |
|
||||
| filter-option | customize filter option logic | ^[false] \| ^[Function]`(pattern: string, option: MentionOption) => boolean` | - |
|
||||
| placement | set popup placement | ^[string]`'bottom' \| 'top'` | `'bottom'` |
|
||||
| show-arrow | whether the dropdown panel has an arrow | ^[boolean] | `false` |
|
||||
| offset | offset of the dropdown panel | ^[number] | `0` |
|
||||
| whole | when backspace is pressed to delete, whether the mention content is deleted as a whole | ^[boolean] | `false` |
|
||||
| check-is-whole | when backspace is pressed to delete, check if the mention is a whole | ^[Function]`(pattern: string, prefix: string) => boolean` | - |
|
||||
| loading | whether the dropdown panel of mentions is in a loading state | ^[boolean] | `false` |
|
||||
| model-value / v-model | input value | ^[string] | - |
|
||||
| popper-class | custom class name for dropdown panel | ^[string] | - |
|
||||
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object] refer to [popper.js doc](https://popper.js.org/docs/v2/) | - |
|
||||
| [input props](./input.md#attributes) | - | - | - |
|
||||
|
||||
### Events
|
||||
|
||||
| Name | Description | Type |
|
||||
| --------------------------------- | ----------------------------------- | ------------------------------------------------------------ |
|
||||
| search | trigger when prefix hit | ^[Function]`(pattern: string, prefix: string) => void` |
|
||||
| select | trigger when user select the option | ^[Function]`(option: MentionOption, prefix: string) => void` |
|
||||
| [input events](./input.md#events) | - | - |
|
||||
|
||||
### Slots
|
||||
|
||||
| Name | Description | Type |
|
||||
| ------------------------------- | ------------------------------------- | ------------------------------------------------- |
|
||||
| label | content as option label | ^[object]`{ item: MentionOption, index: number }` |
|
||||
| loading | content as option loading | - |
|
||||
| header | content at the top of the dropdown | - |
|
||||
| footer | content at the bottom of the dropdown | - |
|
||||
| [input slots](./input.md#slots) | - | - |
|
||||
|
||||
### Exposes
|
||||
|
||||
| Name | Description | Type |
|
||||
| ------- | ----------------------------- | --------------------------------------- |
|
||||
| input | el-input component instance | ^[object]`Ref<InputInstance \| null>` |
|
||||
| tooltip | el-tooltip component instance | ^[object]`Ref<TooltipInstance \| null>` |
|
||||
|
||||
## Type Declarations
|
||||
|
||||
<details>
|
||||
<summary>Show declarations</summary>
|
||||
|
||||
```ts
|
||||
type MentionOption = {
|
||||
value: string
|
||||
label?: string
|
||||
disabled?: boolean
|
||||
[key: string]: any
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
32
docs/examples/mention/basic.vue
Normal file
32
docs/examples/mention/basic.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<el-mention
|
||||
v-model="value"
|
||||
:options="options"
|
||||
style="width: 320px"
|
||||
placeholder="Please input"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
const value = ref('@')
|
||||
|
||||
const options = ref([
|
||||
{
|
||||
label: 'Fuphoenixes',
|
||||
value: 'Fuphoenixes',
|
||||
},
|
||||
{
|
||||
label: 'kooriookami',
|
||||
value: 'kooriookami',
|
||||
},
|
||||
{
|
||||
label: 'Jeremy',
|
||||
value: 'Jeremy',
|
||||
},
|
||||
{
|
||||
label: 'btea',
|
||||
value: 'btea',
|
||||
},
|
||||
])
|
||||
</script>
|
||||
76
docs/examples/mention/form.vue
Normal file
76
docs/examples/mention/form.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
>
|
||||
<el-form-item label="name" prop="name">
|
||||
<el-mention v-model="ruleForm.name" :options="options" />
|
||||
</el-form-item>
|
||||
<el-form-item label="desc" prop="desc">
|
||||
<el-mention v-model="ruleForm.desc" type="textarea" :options="options" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm(ruleFormRef)">
|
||||
Submit
|
||||
</el-button>
|
||||
<el-button @click="resetForm(ruleFormRef)">Reset</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
|
||||
interface RuleForm {
|
||||
name: string
|
||||
desc: string
|
||||
}
|
||||
const ruleFormRef = ref<FormInstance>()
|
||||
const ruleForm = reactive<RuleForm>({
|
||||
name: '',
|
||||
desc: '',
|
||||
})
|
||||
|
||||
const options = ref([
|
||||
{
|
||||
label: 'Fuphoenixes',
|
||||
value: 'Fuphoenixes',
|
||||
},
|
||||
{
|
||||
label: 'kooriookami',
|
||||
value: 'kooriookami',
|
||||
},
|
||||
{
|
||||
label: 'Jeremy',
|
||||
value: 'Jeremy',
|
||||
},
|
||||
{
|
||||
label: 'btea',
|
||||
value: 'btea',
|
||||
},
|
||||
])
|
||||
|
||||
const rules = reactive<FormRules<RuleForm>>({
|
||||
name: [{ required: true, message: 'Please input name', trigger: 'blur' }],
|
||||
desc: [{ required: true, message: 'Please input desc', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
const submitForm = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
console.log('submit!')
|
||||
} else {
|
||||
console.log('error submit!', fields)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
}
|
||||
</script>
|
||||
39
docs/examples/mention/label.vue
Normal file
39
docs/examples/mention/label.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<el-mention
|
||||
v-model="value"
|
||||
:options="options"
|
||||
style="width: 320px"
|
||||
placeholder="Please input"
|
||||
>
|
||||
<template #label="{ item }">
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-avatar :size="24" :src="item.avatar" />
|
||||
<span style="margin-left: 6px">{{ item.value }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-mention>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
const value = ref('')
|
||||
|
||||
const options = ref([
|
||||
{
|
||||
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',
|
||||
},
|
||||
])
|
||||
</script>
|
||||
39
docs/examples/mention/loading.vue
Normal file
39
docs/examples/mention/loading.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<el-mention
|
||||
v-model="value"
|
||||
:options="options"
|
||||
:loading="loading"
|
||||
style="width: 320px"
|
||||
placeholder="Please input"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
import type { MentionOption } from 'element-plus'
|
||||
|
||||
const value = ref('')
|
||||
const loading = ref(false)
|
||||
const options = ref<MentionOption[]>([])
|
||||
|
||||
let timer: ReturnType<typeof setTimeout>
|
||||
const handleSearch = (pattern: string) => {
|
||||
if (timer) clearTimeout(timer)
|
||||
|
||||
loading.value = true
|
||||
timer = setTimeout(() => {
|
||||
options.value = ['Fuphoenixes', 'kooriookami', 'Jeremy', 'btea'].map(
|
||||
(item) => ({
|
||||
label: pattern + item,
|
||||
value: pattern + item,
|
||||
})
|
||||
)
|
||||
loading.value = false
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (timer) clearTimeout(timer)
|
||||
})
|
||||
</script>
|
||||
28
docs/examples/mention/prefix.vue
Normal file
28
docs/examples/mention/prefix.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<el-mention
|
||||
v-model="value"
|
||||
:options="options"
|
||||
:prefix="['@', '#']"
|
||||
style="width: 320px"
|
||||
placeholder="input @ to mention people, # to mention tag"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import type { MentionOption } from 'element-plus'
|
||||
|
||||
const MOCK_DATA: Record<string, string[]> = {
|
||||
'@': ['Fuphoenixes', 'kooriookami', 'Jeremy', 'btea'],
|
||||
'#': ['1.0', '2.0', '3.0'],
|
||||
}
|
||||
const value = ref('')
|
||||
const options = ref<MentionOption[]>([])
|
||||
|
||||
const handleSearch = (_: string, prefix: string) => {
|
||||
options.value = (MOCK_DATA[prefix] || []).map((value) => ({
|
||||
value,
|
||||
}))
|
||||
}
|
||||
</script>
|
||||
33
docs/examples/mention/textarea.vue
Normal file
33
docs/examples/mention/textarea.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<el-mention
|
||||
v-model="value"
|
||||
type="textarea"
|
||||
:options="options"
|
||||
style="width: 320px"
|
||||
placeholder="Please input"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
const value = ref('')
|
||||
|
||||
const options = ref([
|
||||
{
|
||||
label: 'Fuphoenixes',
|
||||
value: 'Fuphoenixes',
|
||||
},
|
||||
{
|
||||
label: 'kooriookami',
|
||||
value: 'kooriookami',
|
||||
},
|
||||
{
|
||||
label: 'Jeremy',
|
||||
value: 'Jeremy',
|
||||
},
|
||||
{
|
||||
label: 'btea',
|
||||
value: 'btea',
|
||||
},
|
||||
])
|
||||
</script>
|
||||
46
docs/examples/mention/whole.vue
Normal file
46
docs/examples/mention/whole.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<el-mention
|
||||
v-model="value1"
|
||||
whole
|
||||
:options="options1"
|
||||
style="width: 320px"
|
||||
placeholder="Please input"
|
||||
/>
|
||||
<el-divider />
|
||||
<el-mention
|
||||
v-model="value2"
|
||||
:options="options2"
|
||||
:prefix="['@', '#']"
|
||||
whole
|
||||
:check-is-whole="checkIsWhole"
|
||||
style="width: 320px"
|
||||
placeholder="input @ to mention people, # to mention tag"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import type { MentionOption } from 'element-plus'
|
||||
|
||||
const MOCK_DATA: Record<string, string[]> = {
|
||||
'@': ['Fuphoenixes', 'kooriookami', 'Jeremy', 'btea'],
|
||||
'#': ['1.0', '2.0', '3.0'],
|
||||
}
|
||||
const value1 = ref('')
|
||||
const value2 = ref('')
|
||||
const options1 = ref<MentionOption[]>(
|
||||
MOCK_DATA['@'].map((value) => ({ value }))
|
||||
)
|
||||
const options2 = ref<MentionOption[]>([])
|
||||
|
||||
const handleSearch = (_: string, prefix: string) => {
|
||||
options2.value = (MOCK_DATA[prefix] || []).map((value) => ({
|
||||
value,
|
||||
}))
|
||||
}
|
||||
|
||||
const checkIsWhole = (pattern: string, prefix: string) => {
|
||||
return (MOCK_DATA[prefix] || []).includes(pattern)
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user