リアルタイムチャットコンポーネントの構築
v-forによるメッセージ一覧、入力バインディング、送信時のemit、新着メッセージ時の最下部へのスクロール
「リアルタイムチャットコンポーネントの構築」はCoddyKit上の無料Vue Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはVue Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Vue Academyコースには全4レッスンが含まれています。
目標:リアルタイムチャットボックス
小さいながらも完全なチャットコンポーネントを組み立てます。スクロール可能なメッセージ一覧を表示し、ユーザーが入力して送信できるようにし、受信したメッセージをリアルタイムで追加します。
ここでは、リアクティブな状態、ライフサイクルフック、DOM へのアクセスを組み合わせます。
メッセージの ref
会話をリアクティブな配列に保持します。各項目は、id、author、text を持つ単純なオブジェクトです。
import { ref } from "vue"
const messages = ref([
{ id: 1, user: "system", text: "Welcome to the room" },
])入力用の ref
v-modelを使って、テキストボックスを別の ref にバインドします。送信前に作成中のメッセージを保持するための ref です。
// 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 = ""
}一覧を表示する
テンプレートでv-forを使ってmessagesを id でキー付けしてループします。各行には author と text を表示します。
<!-- 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 が更新を反映していないためです。
スクロールのタイミングが早すぎるため、最新の行を見逃してしまいます。
コンテナへのテンプレート ref
テンプレート ref を使ってスクロールコンテナを取得し、スクロール位置を読み取ったり設定したりできるようにします。
import { ref } from "vue"
const chatBox = ref(null)
// template: <div ref="chatBox"> ... </div>nextTickでDOMを待機する
nextTickは、Vueが保留中のDOM更新を適用した後に解決されるpromiseを返します。新しいメッセージがDOMに存在するよう、スクロールする前にawaitしてください。
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()
})
})完成したフロー
これでコンポーネントは、メッセージを受信し、リアクティブな状態を更新し、nextTickでDOMの更新を待ってからスクロールするようになりました。送信時も同じ流れになります。シンプルで予測しやすい、リアルタイムな処理です。
async function sendMessage() {
const text = draft.value.trim()
if (!text) return
socket.emit("send", { text })
draft.value = ""
await scrollToBottom()
}クイックチェック
チャットコンポーネントにおけるDOMのタイミングについて、理解度を確認してください。
まとめ
このレッスンでは、リアルタイムチャットコンポーネントを構築しました。重要なポイントは次のとおりです。
- メッセージをリアクティブな
ref配列で管理し、入力途中の内容は独自のrefで管理します。 onMountedでソケットのリスナーを登録し、受信したメッセージを追加します。sendMessageで入力途中の内容を送信し、入力欄をクリアします。- テンプレートrefと
await nextTick()を使い、scrollTop = scrollHeightを設定する前にDOMの更新を待って、最新のメッセージが表示されるようにします。
AI チューターと学ぶ HTML — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 42
- レッスン
- 156
よくある質問
「リアルタイムチャットコンポーネントの構築」レッスンは無料ですか?
はい。「リアルタイムチャットコンポーネントの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Vue Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Vue Academyコースには全4レッスンが含まれています。
「リアルタイムチャットコンポーネントの構築」で何を学びますか?
v-forによるメッセージ一覧、入力バインディング、送信時のemit、新着メッセージ時の最下部へのスクロール ブラウザで直接実行するハンズオンコードでVue Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Vue Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのVue Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「リアルタイムチャットコンポーネントの構築」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このVue Academyレッスンでコードを書いて実行できますか?
はい。すべてのVue Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- ブラウザでのWebSocket入門
- VueでのSocket.ioクライアント
- リアルタイムチャットコンポーネントの構築
- 再接続対応useWebSocket Composable