Mentions

Компонент Mentions предназначен для организации ввода текста с автодополнением упоминаний пользователей, тегов или любых других сущностей. Он особенно полезен в чатах, комментариях, блогах и системах управления контентом, где необходимо интерактивное упоминание объектов в текстовом поле.

Основные свойства

  • v-model:value / value — текущее значение поля. Может быть строкой или массивом объектов, в зависимости от режима работы.
  • placeholder — текст-подсказка в поле ввода.
  • disabled — отключение компонента, делает поле недоступным для ввода.
  • prefix — символ, с которого начинается упоминание (по умолчанию @). Можно использовать любой символ или набор символов.
  • split — разделитель для нескольких упоминаний (например, пробел или запятая).
  • filterOption — функция для фильтрации списка упоминаний. Получает текущий ввод пользователя и объект элемента, должна возвращать true для отображаемых опций.
  • options — массив объектов упоминаний с обязательным полем label для отображения и value для внутреннего идентификатора.

Основные события

  • on-update:value — вызывается при изменении значения поля, позволяет синхронизировать данные с внешним состоянием.
  • on-select — срабатывает при выборе элемента из списка упоминаний. Возвращает объект выбранной опции.
  • on-search — вызывается при вводе текста после символа префикса, передает текущую строку для динамической фильтрации или асинхронного поиска.

Режимы работы

  1. Обычный текст с упоминаниями В этом режиме компонент принимает строку, внутри которой могут быть упоминания. Префикс (@) указывает начало упоминания. Например:

    <n-mentions
      v-model:value="message"
      :options="userOptions"
      placeholder="Введите сообщение"
    />

    Здесь userOptions — массив объектов пользователей:

    [
      { label: 'Иван Иванов', value: 'ivan_ivanov' },
      { label: 'Мария Петрова', value: 'maria_petrova' }
    ]
  2. Множественные упоминания Если требуется поддержка нескольких упоминаний, используется свойство split, которое определяет, где заканчивается одно упоминание и начинается другое:

    <n-mentions
      v-model:value="mentions"
      :options="userOptions"
      split=","
    />

    Значение mentions будет массивом объектов упоминаний, где каждый элемент соответствует отдельному упоминанию.

Кастомизация отображения

  • Слот prefix позволяет изменить отображение префикса упоминания.
  • Слот option даёт полный контроль над тем, как отображается каждая опция в выпадающем списке. Например, можно добавить аватар пользователя или дополнительную информацию:
<n-mentions v-model:value="message" :options="userOptions">
  <template #option="{ option }">
    <div style="display: flex; align-items: center;">
      <img :src="option.avatar" style="width: 24px; height: 24px; border-radius: 50%; margin-right: 8px;" />
      <span>{{ option.label }}</span>
    </div>
  </template>
</n-mentions>

Асинхронный поиск

Для динамического подгружания опций можно использовать событие on-search. Например, запрос к API при вводе текста после префикса:

<n-mentions
  v-model:value="message"
  :options="options"
  @search="handleSearch"
/>

<script>
export default {
  data() {
    return {
      message: '',
      options: []
    }
  },
  methods: {
    async handleSearch(query) {
      const response = await fetch(`/api/users?query=${query}`);
      const data = await response.json();
      this.options = data.map(user => ({ label: user.name, value: user.id }));
    }
  }
}
</script>

Стилизация

Naive UI поддерживает стандартные CSS-переменные для настройки цветов, отступов и шрифтов. Основные переменные для Mentions:

  • --n-mentions-font-size — размер текста.
  • --n-mentions-placeholder-color — цвет placeholder.
  • --n-mentions-option-hover-bg-color — фон опции при наведении.
  • --n-mentions-tag-bg-color — фон выбранного упоминания.

Прямое использование этих переменных позволяет интегрировать компонент в любой дизайн без необходимости переписывать стили через глубокие селекторы.

Советы по использованию

  • Для больших списков лучше реализовать асинхронный поиск, чтобы не перегружать DOM большим количеством опций.
  • Если требуется подсветка упоминаний в тексте после отправки, можно хранить упоминания как объекты и рендерить текст с использованием кастомного компонента для тега.
  • Для поддержки разных префиксов (например, @ и #) можно использовать несколько компонентов Mentions или расширить логику фильтрации через filterOption.

Пример полного компонента

<template>
  <n-mentions
    v-model:value="message"
    :options="userOptions"
    placeholder="Напишите комментарий..."
    split=","
    @search="fetchUsers"
  >
    <template #option="{ option }">
      <div class="user-option">
        <img :src="option.avatar" class="avatar" />
        <span>{{ option.label }}</span>
      </div>
    </template>
  </n-mentions>
</template>

<script>
export default {
  data() {
    return {
      message: '',
      userOptions: []
    }
  },
  methods: {
    async fetchUsers(query) {
      const response = await fetch(`/api/users?query=${query}`);
      const users = await response.json();
      this.userOptions = users.map(u => ({ label: u.name, value: u.id, avatar: u.avatar }));
    }
  }
}
</script>

<style>
.user-option {
  display: flex;
  align-items: center;
  gap: 8px;
}
.avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
}
</style>

Этот пример демонстрирует интеграцию Mentions с асинхронной загрузкой, кастомным отображением опций и поддержкой нескольких упоминаний через split.

Компонент Mentions в Naive UI сочетает простоту использования с гибкостью настройки, позволяя создавать удобный интерфейс для работы с упоминаниями в любом текстовом контексте.