Mentions 提及
提及组件。
何时使用
- 用于在输入中提及某人或某事,常用于发布、聊天或评论功能。
代码演示
基本用法
<template>
<a-mentions autofocus v-model:value="value" @select="onSelect">
<a-mentions-option value="afc163">afc163</a-mentions-option>
<a-mentions-option value="zombieJ">zombieJ</a-mentions-option>
<a-mentions-option value="yesmeck">yesmeck</a-mentions-option>
</a-mentions>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from 'vue';
export default defineComponent({
setup() {
const value = ref<string>('@afc163');
watch(value, () => {
console.log('value', value);
});
const onSelect = (option: { value: string }) => {
console.log('select', option);
};
return {
value,
onSelect,
};
},
});
</script>
通过 prefix 属性自定义触发字符。默认为 @, 可以定义为数组。
<template>
<a-mentions
v-model:value="value"
placeholder="input @ to mention people, # to mention tag"
:prefix="['@', '#']"
@search="onSearch"
>
<a-mentions-option v-for="value in options" :key="value" :value="value">
{{ value }}
</a-mentions-option>
</a-mentions>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
const MOCK_DATA: Record<string, string[]> = {
'@': ['afc163', 'zombiej', 'yesmeck'],
'#': ['1.0', '2.0', '3.0'],
};
export default defineComponent({
setup() {
const prefix = ref<string>('@');
const value = ref<string>('');
const options = computed(() => {
return MOCK_DATA[prefix.value] || [];
});
const onSearch = (_: string, val: string) => {
console.log(_, val);
prefix.value = val;
};
return {
value,
options,
onSearch,
};
},
});
</script>
向上展开建议。
<template>
<a-mentions v-model:value="value" placement="top">
<a-mentions-option value="afc163">afc163</a-mentions-option>
<a-mentions-option value="zombieJ">zombieJ</a-mentions-option>
<a-mentions-option value="yesmeck">yesmeck</a-mentions-option>
</a-mentions>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref<string>('');
return {
value,
};
},
});
</script>
匹配内容列表为异步返回时。
<template>
<a-mentions v-model:value="value" :loading="loading" @search="onSearch">
<a-mentions-option v-for="{ login, avatar_url: avatar } in users" :key="login" :value="login">
<img :src="avatar" :alt="login" style="width: 20px; margin-right: 8px" />
<span>{{ login }}</span>
</a-mentions-option>
</a-mentions>
</template>
<script lang="ts">
import { debounce } from 'lodash-es';
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value = ref<string>('');
const loading = ref<boolean>(false);
const users = ref<string[]>([]);
const search = ref<string>('');
const loadGithubUsers = debounce((key: string) => {
if (!key) {
users.value = [];
return;
}
fetch(`https://api.github.com/search/users?q=${key}`)
.then(res => res.json())
.then(({ items = [] }) => {
if (search.value !== key) return;
users.value = items.slice(0, 10);
loading.value = false;
});
}, 800);
const onSearch = (searchValue: string) => {
search.value = searchValue;
loading.value = !!searchValue;
console.log(!!searchValue);
users.value = [];
console.log('Search:', searchValue);
loadGithubUsers(searchValue);
};
return {
value,
loading,
users,
loadGithubUsers,
onSearch,
};
},
});
</script>
通过 disabled
属性设置是否生效。通过 readonly
属性设置是否只读。
<template>
<div>
<div style="margin-bottom: 10px">
<a-mentions v-model:value="value1" placeholder="this is disabled Mentions" disabled>
<a-mentions-option v-for="value in options" :key="value" :value="value">
{{ value }}
</a-mentions-option>
</a-mentions>
</div>
<a-mentions v-model:value="value2" placeholder="this is readOnly a-mentions" readonly>
<a-mentions-option v-for="value in options" :key="value" :value="value">
{{ value }}
</a-mentions-option>
</a-mentions>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const value1 = ref<string>('');
const value2 = ref<string>('');
const options = ref<string[]>(['afc163', 'zombieJ', 'yesmeck']);
return {
value1,
value2,
options,
};
},
});
</script>
Top coders
Bio
SubmitReset
配合 Form 使用。
<template>
<a-form layout="horizontal">
<a-form-item
label="Top coders"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
name="coders"
v-bind="validateInfos.coders"
>
<a-mentions rows="1" v-model:value="modelRef.coders">
<a-mentions-option value="afc163">afc163</a-mentions-option>
<a-mentions-option value="zombieJ">zombieJ</a-mentions-option>
<a-mentions-option value="yesmeck">yesmeck</a-mentions-option>
</a-mentions>
</a-form-item>
<a-form-item
label="Bio"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
name="bio"
v-bind="validateInfos.bio"
>
<a-mentions
rows="3"
placeholder="You can use @ to ref user here"
v-model:value="modelRef.bio"
>
<a-mentions-option value="afc163">afc163</a-mentions-option>
<a-mentions-option value="zombieJ">zombieJ</a-mentions-option>
<a-mentions-option value="yesmeck">yesmeck</a-mentions-option>
</a-mentions>
</a-form-item>
<a-form-item :wrapper-col="{ span: 12, offset: 5 }">
<a-button type="primary" @click="handleSubmit">Submit</a-button>
<a-button style="margin-left: 8px" @click="resetFields">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script>
import { Mentions } from 'ant-design-vue';
import { defineComponent, reactive } from 'vue';
import { useForm } from '@ant-design-vue/use';
const { getMentions } = Mentions;
export default defineComponent({
setup() {
const checkMention = async (rule, value) => {
const mentions = getMentions(value);
if (mentions.length < 2) {
return Promise.reject('More than one must be selected!');
} else {
return Promise.resolve();
}
};
const modelRef = reactive({
bio: '',
coders: '',
});
const rulesRef = reactive({
bio: [{ required: true, message: 'Must input bio' }],
coders: [{ required: true, validator: checkMention }],
});
const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef);
const handleSubmit = e => {
e.preventDefault();
validate()
.then(() => {
console.log('Submit!!!', modelRef);
})
.catch(errors => {
console.log('Errors in the form!!!', errors);
});
};
return {
modelRef,
resetFields,
validateInfos,
handleSubmit,
};
},
});
</script>
API
Mentions
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
autofocus | 自动获得焦点 | boolean | false |
defaultValue | 默认值 | string | |
filterOption | 自定义过滤逻辑 | false | (input: string, option: OptionProps) => boolean | |
notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | ‘Not Found’ |
placement | 弹出层展示位置 | top | bottom | bottom |
prefix | 设置触发关键字 | string | string[] | ‘@’ |
split | 设置选中项前后分隔符 | string | ‘ ‘ |
validateSearch | 自定义触发验证逻辑 | (text: string, props: MentionsProps) => void | |
value(v-model) | 设置值 | string | |
getPopupContainer | 指定建议框挂载的 HTML 节点 | () => HTMLElement |
事件
事件名称 | 说明 | 回调参数 |
---|---|---|
blur | 失去焦点的时回调 | function |
change | 值改变时触发 | function(value: string) |
focus | 获得焦点时回调 | function |
search | 文本框值变化时回调 | function(value: string, prefix: string) |
select | 选择选项时触发 | function(option: OptionProps, prefix: string) |
Mentions 方法
名称 | 描述 |
---|---|
blur() | 移除焦点 |
focus() | 获取焦点 |
Option
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
value | 选择时填充的值 | string | ‘’ |