0Pricing
Vue Academy · บทเรียน

การสร้างคอมโพเนนต์แชตแบบเรียลไทม์

รายการข้อความด้วย 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐาน WebSocket ในเบราว์เซอร์
  2. ไคลเอ็นต์ Socket.io กับ Vue
  3. การสร้างคอมโพเนนต์แชตแบบเรียลไทม์
  4. คอมโพสิเบิล useWebSocket พร้อมการเชื่อมต่อใหม่
← กลับไปที่ Vue Academy