Создание компонента чата в реальном времени
Список сообщений с v-for, привязка ввода, отправка события при подтверждении и прокрутка вниз при новом сообщении
«Создание компонента чата в реальном времени» — бесплатный урок Vue Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.
Цель: окно чата в реальном времени
Мы соберём небольшой, но полноценный компонент чата: он отображает прокручиваемый список сообщений, позволяет пользователю вводить и отправлять сообщения, а также добавляет входящие сообщения в реальном времени.
В этом примере объединяются реактивное состояние, хуки жизненного цикла и доступ к DOM.
Ссылка на сообщения
Храните переписку в реактивном массиве. Каждая запись представляет собой простой объект с идентификатором, автором и текстом.
import { ref } from "vue"
const messages = ref([
{ id: 1, user: "system", text: "Welcome to the room" },
])Ссылка для поля ввода
Свяжите текстовое поле с отдельной ссылкой с помощью v-model. В ней хранится составляемое сообщение до его отправки.
// template:
// <input v-model="draft" @keyup.enter="sendMessage" />
const draft = ref("")Регистрация слушателя сокета
В onMounted подпишитесь на входящие сообщения и добавляйте каждое из них в массив. Использование onMounted гарантирует готовность компонента до подключения обработчиков.
import { onMounted } from "vue"
onMounted(() => {
socket.on("message", (msg) => {
messages.value.push(msg)
})
})Отправка сообщения
Функция sendMessage передаёт черновик на сервер и очищает поле ввода. Перед отправкой мы проверяем, что строка не пуста.
function sendMessage() {
const text = draft.value.trim()
if (!text) return
socket.emit("send", { text })
draft.value = ""
}Отображение списка
Шаблон перебирает messages с помощью v-for, используя идентификатор в качестве ключа. В каждой строке отображаются автор и текст.
<!-- template -->
<div ref="chatBox" class="chat">
<p v-for="m in messages" :key="m.id">
<strong>{{ m.user }}:</strong> {{ m.text }}
</p>
</div>Проблема прокрутки
Когда поступает новое сообщение, пользователь ожидает, что представление останется прокрученным до нижней границы. Но если прокрутить его сразу после добавления сообщения в массив, новой строки ещё нет в DOM — Vue ещё не применил обновление.
Прокрутка происходит слишком рано, и последняя строка остаётся за пределами видимой области.
Ссылка на контейнер в шаблоне
Получите контейнер прокрутки через ссылку шаблона, чтобы читать и задавать его положение прокрутки.
import { ref } from "vue"
const chatBox = ref(null)
// template: <div ref="chatBox"> ... </div>Ожидание DOM с помощью nextTick
nextTick возвращает промис, который выполняется после того, как Vue применит ожидающие обновления DOM. Дождитесь его выполнения перед прокруткой, чтобы новое сообщение появилось в DOM.
import { nextTick } from "vue"
async function scrollToBottom() {
await nextTick()
const el = chatBox.value
el.scrollTop = el.scrollHeight
}Прокрутка после каждого нового сообщения
Вызывайте scrollToBottom сразу после добавления сообщения — и для входящих, и для исходящих сообщений. Установка scrollTop = scrollHeight перемещает прокрутку в самый низ.
onMounted(() => {
socket.on("message", async (msg) => {
messages.value.push(msg)
await scrollToBottom()
})
})Полный процесс
Теперь компонент получает сообщение, обновляет реактивное состояние, дожидается обновления DOM с помощью nextTick, а затем прокручивает содержимое. Отправка проходит по тому же пути. Чисто, предсказуемо, в реальном времени.
async function sendMessage() {
const text = draft.value.trim()
if (!text) return
socket.emit("send", { text })
draft.value = ""
await scrollToBottom()
}Быстрая проверка
Проверьте, насколько хорошо Вы понимаете синхронизацию с DOM в компоненте чата.
Итоги
В этом уроке Вы создали компонент чата, работающий в реальном времени. Главное:
- Храните сообщения в реактивном массиве
ref, а черновик — в отдельном ref. - Регистрируйте обработчик сокета в
onMountedи добавляйте входящие сообщения. sendMessageотправляет черновик и очищает поле ввода.- Используйте ссылку на элемент шаблона и
await nextTick()перед установкойscrollTop = scrollHeight, чтобы было видно последнее сообщение.
Изучай HTML с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 42
- Уроки
- 156
Часто задаваемые вопросы
Урок «Создание компонента чата в реальном времени» бесплатный?
Да — полный текст урока «Создание компонента чата в реальном времени» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.
Чему я научусь в уроке «Создание компонента чата в реальном времени»?
Список сообщений с v-for, привязка ввода, отправка события при подтверждении и прокрутка вниз при новом сообщении Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Vue Academy?
Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Создание компонента чата в реальном времени»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Vue Academy?
Да. Каждый урок Vue Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы WebSocket в браузере
- Клиент Socket.io с Vue
- Создание компонента чата в реальном времени
- Композируемый модуль useWebSocket с переподключением