การสร้างคอมโพเนนต์แชตแบบเรียลไทม์
รายการข้อความด้วย v-for การผูก input การ emit เมื่อส่ง และการเลื่อนไปด้านล่างเมื่อมีข้อความใหม่
การสร้างคอมโพเนนต์แชตแบบเรียลไทม์ เป็นบทเรียน Vue Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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จะส่งข้อความร่างออกไปและล้างช่องป้อนข้อมูล- ใช้ template ref ร่วมกับ
await nextTick()ก่อนกำหนดscrollTop = scrollHeightเพื่อให้เห็นข้อความล่าสุด
คำถามที่พบบ่อย
บทเรียน “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Vue Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Vue Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์”
รายการข้อความด้วย v-for การผูก input การ emit เมื่อส่ง และการเลื่อนไปด้านล่างเมื่อมีข้อความใหม่ คุณปฏิบัติ Vue Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Vue Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Vue Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Vue Academy นี้ได้ไหม
ได้ บทเรียน Vue Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน WebSocket ในเบราว์เซอร์
- ไคลเอ็นต์ Socket.io กับ Vue
- การสร้างคอมโพเนนต์แชตแบบเรียลไทม์
- คอมโพสิเบิล useWebSocket พร้อมการเชื่อมต่อใหม่