You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/th/7-bank-project/1-template-route
localizeflow[bot] 4dc412aa0e
chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes)
7 months ago
..
README.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago

README.md

สร้างแอปธนาคาร ภาค 1: HTML เทมเพลตและเส้นทางในเว็บแอป

journey
    title การเดินทางพัฒนาแอปธนาคารของคุณ
    section พื้นฐาน SPA
      เข้าใจแอปหน้าเดียว: 3: Student
      เรียนรู้แนวคิดเทมเพลต: 4: Student
      เชี่ยวชาญการจัดการ DOM: 4: Student
    section ระบบเส้นทาง
      นำทางฝั่งลูกค้า: 4: Student
      จัดการประวัติการเข้าชมเบราว์เซอร์: 5: Student
      สร้างระบบนำทาง: 5: Student
    section รูปแบบการทำงานระดับมืออาชีพ
      สร้างสถาปัตยกรรมแบบโมดูลาร์: 5: Student
      ใช้แนวปฏิบัติที่ดีที่สุด: 5: Student
      สร้างประสบการณ์ผู้ใช้: 5: Student

เมื่อคอมพิวเตอร์นำทางของ Apollo 11 นำทางไปยังดวงจันทร์ในปี 1969 มันต้องสลับระหว่างโปรแกรมต่างๆ โดยไม่ต้องรีสตาร์ทระบบทั้งหมด เว็บแอปสมัยใหม่ก็ทำงานคล้ายกัน พวกมันเปลี่ยนสิ่งที่คุณเห็นโดยไม่ต้องโหลดทุกอย่างใหม่ทั้งหมด ซึ่งสร้างประสบการณ์ที่ราบรื่นและตอบสนองที่ผู้ใช้คาดหวังในปัจจุบัน

ต่างจากเว็บไซต์แบบดั้งเดิมที่รีโหลดหน้าเว็บทั้งหน้าเมื่อมีการโต้ตอบ เว็บแอปสมัยใหม่จะอัปเดตเพียงส่วนที่ต้องการเปลี่ยนแปลง วิธีนี้คล้ายกับการที่ศูนย์ควบคุมภารกิจเปลี่ยนหน้าจอแสดงผลระหว่างการสื่อสารอย่างต่อเนื่อง เพื่อสร้างประสบการณ์ที่ลื่นไหลซึ่งเราได้คุ้นเคย

นี่คือเหตุผลที่ทำให้ความแตกต่างชัดเจนมาก:

แอปแบบหลายหน้าดั้งเดิม แอปหน้าเดียวสมัยใหม่
การนำทาง รีโหลดหน้าทั้งหมดทุกครั้งที่เปลี่ยนหน้าจอ
ประสิทธิภาพ ช้ากว่าเพราะต้องดาวน์โหลด HTML ทั้งหมด
ประสบการณ์ผู้ใช้ กระพริบหน้าเว็บแบบกระโชกโฮกฮาก
การแชร์ข้อมูล ยากระหว่างหน้าเว็บต่างๆ
การพัฒนา มีหลายไฟล์ HTML ให้ดูแล

เข้าใจวิวัฒนาการ:

  • แอปแบบดั้งเดิม ต้องร้องขอเซิร์ฟเวอร์ทุกครั้งที่นำทาง
  • SPA แบบสมัยใหม่ โหลดครั้งเดียวแล้วอัปเดตเนื้อหาโดยใช้ JavaScript
  • ความคาดหวังของผู้ใช้ ปัจจุบันต้องการปฏิสัมพันธ์ที่รวดเร็วและไร้รอยต่อ
  • ประโยชน์ทางประสิทธิภาพ รวมทั้งลดแบนด์วิดท์และตอบสนองได้เร็วขึ้น

ในบทเรียนนี้ เราจะสร้างแอปธนาคารที่มีหลายหน้าจอที่ไหลลื่นเหมือนกัน เช่นเดียวกับนักวิทยาศาสตร์ที่ใช้เครื่องมือแบบโมดูลที่สามารถปรับแต่งได้สำหรับการทดลองต่างๆ เราจะใช้เทมเพลต HTML เป็นส่วนประกอบที่นำกลับมาใช้ซ้ำได้และแสดงผลเมื่อต้องการ

คุณจะได้ทำงานกับเทมเพลต HTML (แบบร่างซ้ำได้สำหรับหน้าจอต่างๆ), การจัดเส้นทางด้วย JavaScript (ระบบที่สลับหน้าจอ), และประวัติของเบราว์เซอร์ (API ที่ทำให้ปุ่มย้อนกลับทำงานตามที่คาดหวัง) เทคนิคพื้นฐานเดียวกันนี้ใช้ในเฟรมเวิร์กเช่น React, Vue, และ Angular

เมื่อจบบทนี้ คุณจะมีแอปธนาคารทำงานได้จริงที่แสดงหลักการของแอปแบบหน้าเดียวมืออาชีพ

mindmap
  root((Single-Page Applications))
    Architecture
      Template System
      Client-side Routing
      State Management
      Event Handling
    Templates
      ส่วนประกอบที่นำกลับมาใช้ใหม่ได้
      เนื้อหาแบบไดนามิก
      การจัดการ DOM
      การสลับเนื้อหา
    Routing
      การจัดการ URL
      History API
      ฟังก์ชันนำทาง
      การรวมเบราว์เซอร์
    User Experience
      การนำทางที่รวดเร็ว
      การเปลี่ยนผ่านที่ราบรื่น
      สถานะที่สม่ำเสมอ
      การโต้ตอบที่ทันสมัย
    Performance
      ลดคำขอบริการเซิร์ฟเวอร์
      การเปลี่ยนผ่านหน้าเพจที่รวดเร็วขึ้น
      การใช้ทรัพยากรอย่างมีประสิทธิภาพ
      การตอบสนองที่ดีขึ้น

แบบทดสอบก่อนเรียน

แบบทดสอบก่อนเรียน

สิ่งที่คุณต้องเตรียม

เราต้องมีเว็บเซิร์ฟเวอร์ท้องถิ่นเพื่อทดสอบแอปธนาคารของเรา ไม่ต้องกังวล มันง่ายกว่าที่คิด! หากคุณยังไม่มีเซิร์ฟเวอร์ ให้ติดตั้ง Node.js แล้วรันคำสั่ง npx lite-server จากโฟลเดอร์โปรเจกต์ของคุณ คำสั่งนี้จะเปิดเซิร์ฟเวอร์ท้องถิ่นและเปิดแอปของคุณในเบราว์เซอร์โดยอัตโนมัติ

การเตรียมตัว

บนคอมพิวเตอร์ของคุณ ให้สร้างโฟลเดอร์ชื่อ bank และภายในโฟลเดอร์นั้นสร้างไฟล์ชื่อ index.html เราจะเริ่มจาก boilerplate HTML นี้:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bank App</title>
  </head>
  <body>
    <!-- This is where you'll work -->
  </body>
</html>

สิ่งที่ boilerplate นี้มีให้:

  • กำหนด โครงสร้างเอกสาร HTML5 พร้อมประกาศ DOCTYPE ที่ถูกต้อง
  • ตั้งค่า การเข้ารหัสตัวอักษรเป็น UTF-8 รองรับข้อความหลากภาษา
  • เปิดใช้ การออกแบบตอบสนองด้วย meta tag viewport สำหรับความเข้ากันได้บนมือถือ
  • ตั้งค่า ชื่อเรื่องให้แสดงในแท็บของเบราว์เซอร์
  • สร้าง ส่วน body ที่สะอาดไว้สำหรับสร้างแอปของเรา

📁 ภาพรวมโครงสร้างโปรเจกต์

เมื่อจบบทเรียนนี้ โปรเจกต์ของคุณจะมี:

bank/
├── index.html      <!-- Main HTML with templates -->
├── app.js          <!-- Routing and navigation logic -->
└── style.css       <!-- (Optional for future lessons) -->

ความรับผิดชอบของไฟล์:

  • index.html: เก็บทุกเทมเพลตและโครงสร้างแอป
  • app.js: จัดการเส้นทาง, นำทาง และจัดการเทมเพลต
  • เทมเพลต: กำหนด UI สำหรับหน้าเข้าสู่ระบบ, แดชบอร์ด และหน้าจออื่นๆ

เทมเพลต HTML

เทมเพลตแก้ปัญหาจากพื้นฐานในเว็บดีเวลอปเมนต์ เมื่อกูเตนเบิร์กประดิษฐ์การพิมพ์แบบตัวเรียงที่ขยับได้นั้นในทศวรรษ 1440 เขาตระหนักว่าแทนที่จะปั๊มหน้าทั้งหน้า เขาสามารถสร้างบล็อกตัวอักษรที่ใช้ซ้ำได้และจัดเรียงต่าง ๆ ตามต้องการ เทมเพลต HTML ทำงานบนหลักการเดียวกัน แทนที่จะสร้างไฟล์ HTML แยกสำหรับแต่ละหน้าจอ คุณกำหนดโครงสร้างที่นำกลับมาใช้ซ้ำได้และแสดงผลเมื่อต้องการ

flowchart TD
    A["📋 กำหนดแม่แบบ"] --> B["💬 ซ่อนใน DOM"]
    B --> C["🔍 JavaScript ค้นหาแม่แบบ"]
    C --> D["📋 สำเนาเนื้อหาแม่แบบ"]
    D --> E["🔗 แนบกับ DOM ที่มองเห็นได้"]
    E --> F["👁️ ผู้ใช้เห็นเนื้อหา"]
    
    G["แม่แบบเข้าสู่ระบบ"] --> A
    H["แม่แบบแดชบอร์ด"] --> A
    I["แม่แบบในอนาคต"] --> A
    
    style A fill:#e3f2fd
    style D fill:#e8f5e8
    style F fill:#fff3e0
    style B fill:#f3e5f5

คิดว่าเทมเพลตเหมือนแผนผังสำหรับหลายส่วนของแอปคุณ เหมือนกับสถาปนิกที่สร้างแผนผังเพียงครั้งเดียวและใช้ซ้ำหลายครั้งแทนที่จะวาดห้องเหมือนกันซ้ำ เราจะสร้างเทมเพลตเพียงครั้งเดียวและสร้างอินสแตนซ์เมื่อจำเป็น เบราว์เซอร์จะเก็บเทมเพลตเหล่านี้ไว้จนกว่า JavaScript จะเรียกใช้งาน

ถ้าคุณอยากสร้างหลายหน้าจอสำหรับเว็บเพจ ทางหนึ่งคือสร้างไฟล์ HTML แยกสำหรับแต่ละหน้าที่ต้องแสดง อย่างไรก็ตามแนวทางนี้มีข้อไม่สะดวกบางประการ:

  • คุณต้องรีโหลด HTML ทั้งหมดเมื่อเปลี่ยนหน้าจอ ซึ่งอาจช้า
  • ยากต่อการแชร์ข้อมูลระหว่างหน้าจอต่างๆ

อีกวิธีหนึ่งคือมีไฟล์ HTML เพียงไฟล์เดียว และกำหนด เทมเพลต HTML หลายอันโดยใช้ <template> เทมเพลตคือบล็อก HTML ที่นำกลับมาใช้ซ้ำได้แต่เบราว์เซอร์จะไม่แสดงจนกว่าจะมีการสร้างอินสแตนซ์ด้วย JavaScript

มาสร้างกันเลย

เราจะสร้างแอปธนาคารที่มีหน้าจอหลักสองหน้า: หน้าเข้าสู่ระบบและแดชบอร์ด ก่อนอื่น มาสร้างอิลิเมนต์ตัวแทนใน body ของ HTML เราจะใช้ตรงนี้เพื่อแสดงหน้าจอต่างๆ

<div id="app">Loading...</div>

เข้าใจอิลิเมนต์ตัวแทนนี้:

  • สร้าง ภาชนะที่มี ID "app" เพื่อแสดงทุกหน้าจอ
  • แสดง ข้อความโหลดจนกว่า JavaScript จะเริ่มทำงานและแสดงหน้าจอแรก
  • มอบ จุดยึดเดียวสำหรับเนื้อหาแบบไดนามิกของเรา
  • เปิดใช้งาน การเข้าถึงอย่างง่ายจาก JavaScript ด้วย document.getElementById()

💡 ทริคโปร: เนื่องจากเนื้อหาของอิลิเมนต์นี้จะถูกเปลี่ยนแปลง เราสามารถใส่ข้อความหรือไอคอนไว้ระหว่างโหลดแอปได้

ถัดไป, เพิ่มด้านล่างนี้เป็นเทมเพลต HTML สำหรับหน้าล็อกอิน ตอนนี้ใส่แค่หัวเรื่องกับส่วนที่มีลิงก์ใช้สำหรับนำทาง

<template id="login">
  <h1>Bank App</h1>
  <section>
    <a href="/dashboard">Login</a>
  </section>
</template>

แยกแยะเทมเพลตล็อกอินนี้:

  • กำหนด เทมเพลตด้วย ID เฉพาะ "login" เพื่อจับเป้าหมายด้วย JavaScript
  • รวม หัวเรื่องหลักที่แสดงแบรนด์ของแอป
  • มี อิลิเมนต์ <section> เชิงความหมายเพื่อจัดกลุ่มเนื้อหาที่เกี่ยวข้อง
  • ให้ ลิงก์นำทางที่จะพาผู้ใช้ไปแดชบอร์ด

จากนั้นเพิ่มอีกเทมเพลต HTML สำหรับหน้าแดชบอร์ด หน้านี้จะประกอบด้วยหลายส่วน:

  • หัวข้อพร้อมชื่อเรื่องและลิงก์ออกจากระบบ
  • ยอดคงเหลือปัจจุบันของบัญชีธนาคาร
  • รายการธุรกรรม แสดงในตาราง
<template id="dashboard">
  <header>
    <h1>Bank App</h1>
    <a href="/login">Logout</a>
  </header>
  <section>
    Balance: 100$
  </section>
  <section>
    <h2>Transactions</h2>
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Object</th>
          <th>Amount</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </section>
</template>

เข้าใจส่วนต่างๆ ของแดชบอร์ดนี้:

  • สร้างโครงสร้างหน้า ด้วยอิลิเมนต์เชิงความหมาย <header> ซึ่งมีการนำทาง
  • แสดง ชื่อแอปอย่างสม่ำเสมอเพื่อสร้างแบรนด์
  • ให้ ลิงก์ออกจากระบบนำไปสู่หน้าล็อกอิน
  • แสดง ยอดเงินคงเหลือในส่วนที่จัดไว้เฉพาะ
  • จัดการ ข้อมูลธุรกรรมโดยใช้ตาราง HTML ที่มีโครงสร้างถูกต้อง
  • กำหนด ส่วนหัวของตารางสำหรับวันที่, วัตถุ, และจำนวนเงิน
  • เว้น ส่วนเนื้อหาของตารางว่างเพื่อจะเติมเนื้อหาแบบไดนามิกในภายหลัง

💡 ทริคโปร: เมื่อสร้างเทมเพลต HTML ถ้าคุณต้องการดูว่าหน้าตาเป็นยังไง คุณสามารถแสดงความคิดเห็นบรรทัด <template> และ </template> โดยใช้ <!-- -->

🔄 ตรวจสอบความเข้าใจเชิงการสอน

ความเข้าใจระบบเทมเพลต: ก่อนลงมือเขียน JavaScript ให้แน่ใจว่าคุณเข้าใจ:

  • เทมเพลตแตกต่างจากอิลิเมนต์ HTML ธรรมดาอย่างไร
  • ทำไมเทมเพลตถึงซ่อนจนกว่า JavaScript จะเปิดใช้งาน
  • ความสำคัญของโครงสร้าง HTML เชิงความหมายในเทมเพลต
  • เทมเพลตช่วยให้สร้างส่วนติดต่อผู้ใช้ที่นำกลับมาใช้ซ้ำได้อย่างไร

ทดสอบตัวเองด่วน: จะเกิดอะไรขึ้นถ้าคุณลบแท็ก <template> ออกจากรอบ HTML ของคุณ? คำตอบ: เนื้อหาจะเห็นได้ทันทีและสูญเสียฟังก์ชันของเทมเพลต

ประโยชน์ทางสถาปัตยกรรม: เทมเพลตให้:

  • นำกลับมาใช้ซ้ำได้: กำหนดครั้งเดียว ใช้หลายครั้ง
  • ประสิทธิภาพ: ไม่ต้องวิเคราะห์ HTML ซ้ำ
  • การบำรุงรักษา: โครงสร้าง UI รวมศูนย์
  • ความยืดหยุ่น: สลับเนื้อหาแบบไดนามิก

ทำไมคุณคิดว่าเราใช้แอตทริบิวต์ id บนเทมเพลต? เราสามารถใช้สิ่งอื่นได้ไหม เช่น คลาส?

ทำให้เทมเพลตมีชีวิตด้วย JavaScript

ตอนนี้เราต้องทำให้เทมเพลตทำงานได้ เหมือนกับเครื่องพิมพ์ 3 มิติที่นำแบบร่างดิจิทัลมาเปลี่ยนเป็นวัตถุจริง JavaScript จะนำเทมเพลตที่ซ่อนไว้สร้างเป็นอิลิเมนต์ที่มองเห็นและโต้ตอบได้

กระบวนการนี้มีสามขั้นตอนหลักที่เป็นรากฐานของการพัฒนาเว็บสมัยใหม่ เมื่อเข้าใจแบบแผนนี้ คุณจะเห็นมันทั่วทั้งหลายเฟรมเวิร์กและไลบรารี

ถ้าคุณทดลองเปิดไฟล์ HTML ปัจจุบันนี้ในเบราว์เซอร์ คุณจะเห็นข้อความ Loading... ค้างอยู่ เพราะเราต้องเพิ่มโค้ด JavaScript เพื่อสร้างและแสดงเทมเพลต HTML

การสร้างอินสแตนซ์เทมเพลตมักทำในสามขั้นตอน:

  1. ดึงอิลิเมนต์เทมเพลตจาก DOM เช่นใช้ document.getElementById
  2. คลอน (clone) เทมเพลตโดยใช้ cloneNode
  3. แนบเทมเพลตที่คลอนแล้วเข้ากับ DOM ภายใต้อิลิเมนต์ที่มองเห็นได้ เช่นใช้ appendChild
flowchart TD
    A[🔍 ขั้นตอนที่ 1: ค้นหาเทมเพลต] --> B[📋 ขั้นตอนที่ 2: โคลนเทมเพลต]
    B --> C[🔗 ขั้นตอนที่ 3: แนบกับ DOM]
    
    A1["document.getElementById('login')"] --> A
    B1["template.content.cloneNode(true)"] --> B  
    C1["app.appendChild(view)"] --> C
    
    C --> D[👁️ เทมเพลตแสดงผลผู้ใช้]
    
    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0

อธิบายภาพกระบวนการนี้:

  • ขั้นตอนที่ 1 หาเทมเพลตที่ซ่อนอยู่ในโครงสร้าง DOM
  • ขั้นตอนที่ 2 สร้างสำเนาทำงานที่สามารถแก้ไขได้อย่างปลอดภัย
  • ขั้นตอนที่ 3 ใส่สำเนานี้ลงในพื้นที่หน้าเว็บที่มองเห็นได้
  • ผลลัพธ์ คือหน้าจอที่ใช้งานได้ซึ่งผู้ใช้โต้ตอบได้

ทำไมเราจึงต้องคลอนเทมเพลตก่อนแนบมันเข้ากับ DOM? คุณคิดว่าจะเกิดอะไรขึ้นถ้าเราข้ามขั้นตอนนี้?

งานที่ต้องทำ

สร้างไฟล์ใหม่ชื่อ app.js ในโฟลเดอร์โปรเจกต์ของคุณและนำเข้าไฟล์นี้ในส่วน <head> ของ HTML:

<script src="app.js" defer></script>

เข้าใจการนำเข้า script นี้:

  • ลิงก์ ไฟล์ JavaScript เข้ากับเอกสาร HTML ของเรา
  • ใช้ แอตทริบิวต์ defer เพื่อให้สคริปต์ทำงานหลังจากวิเคราะห์ HTML เสร็จ
  • เปิดใช้งาน การเข้าถึงทุกอิลิเมนต์ DOM เพราะโหลดเสร็จสมบูรณ์ก่อนรันสคริปต์
  • ปฏิบัติตาม แนวทางปฏิบัติที่ดีที่สุดสมัยใหม่สำหรับการโหลดสคริปต์และประสิทธิภาพ

ตอนนี้ใน app.js, เราจะสร้างฟังก์ชันใหม่ชื่อ updateRoute:

function updateRoute(templateId) {
  const template = document.getElementById(templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

ทีละขั้นตอน นี่คือสิ่งที่เกิดขึ้น:

  • หา อิลิเมนต์เทมเพลตโดยใช้ ID เฉพาะ
  • สร้าง สำเนาลึกของเนื้อหาเทมเพลตด้วย cloneNode(true)
  • หา ภาชนะแอปที่จะใช้แสดงเนื้อหา
  • ล้าง เนื้อหาที่มีอยู่ก่อนหน้าทิ้งจากภาชนะแอป
  • แทรก เนื้อหาเทมเพลตที่คลอนแล้วลงใน DOM ที่มองเห็นได้

ตอนนี้เรียกใช้ฟังก์ชันนี้โดยส่งเทมเพลตหนึ่งอันและดูผลลัพธ์

updateRoute('login');

ฟังก์ชันนี้ทำอะไร:

  • เปิดใช้งาน เทมเพลตล็อกอินโดยส่ง ID ของมันเป็นพารามิเตอร์
  • สาธิต การสลับหน้าจอของแอปแบบโปรแกรมเมติก
  • แสดง หน้าจอเข้าสู่ระบบแทนข้อความ "Loading..."

จุดประสงค์ของบรรทัด app.innerHTML = ''; คืออะไร? จะเกิดอะไรขึ้นถ้าไม่มีบรรทัดนี้?

การสร้างเส้นทาง (Routes)

Routing คือการเชื่อมโยง URLs กับเนื้อหาที่ถูกต้อง ลองนึกภาพนักโทรศัพท์สลับสายที่เชื่อมสายโทรเข้ากับปลายทางถูกต้อง Web routing ทำงานแบบเดียวกัน รับคำขอ URL และตัดสินใจว่าแสดงเนื้อหาอะไร

flowchart LR
    A["🌐 เส้นทาง URL<br/>/dashboard"] --> B["🗺️ วัตถุเส้นทาง<br/>ค้นหา"]
    B --> C["🎯 ID แม่แบบ<br/>'dashboard'"]
    C --> D["📌 ค้นหาแม่แบบ<br/>getElementById"]
    D --> E["👁️ แสดงหน้าจอ<br/>คัดลอก & แทรก"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ ไม่พบ"]
    I --> J["🔄 เปลี่ยนเส้นทางไป /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

โดยปกติแล้ว เซิร์ฟเวอร์เว็บจะส่งไฟล์ HTML ต่างกันสำหรับ URLs ต่างๆ เพราะเราเขียนแอปหน้าเดียว เราต้องจัดการ routing นี้เองด้วย JavaScript ซึ่งช่วยให้เราควบคุมประสบการณ์ผู้ใช้และประสิทธิภาพได้ดีขึ้น

flowchart LR
    A["🌐 เส้นทาง URL<br/>/dashboard"] --> B["🗺️ วัตถุเส้นทาง<br/>ค้นหา"]
    B --> C["🎯 รหัสแม่แบบ<br/>'dashboard'"]
    C --> D["📄 ค้นหาแม่แบบ<br/>getElementById"]
    D --> E["👁️ แสดงหน้าจอ<br/>คัดลอก & เพิ่ม"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ ไม่พบ"]
    I --> J["🔄 เปลี่ยนเส้นทางไป /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

เข้าใจการไหลของ routing:

  • การเปลี่ยน URL กระตุ้นการมองหาเส้นทางในระบบของเรา
  • เส้นทางที่มีอยู่ แมปกับ ID เทมเพลตเฉพาะเพื่อเรนเดอร์
  • เส้นทางที่ไม่มีอยู่ จะมีพฤติกรรมสำรองเพื่อป้องกันสถานะเสีย
  • การแสดงผลเทมเพลต ตามกระบวนการสามขั้นตอนที่เราเรียนมาก่อนหน้า

เมื่อพูดถึงเว็บแอป เราเรียก Routing ว่าเป็นการจับคู่ URLs กับหน้าจอที่ควรแสดง ในเว็บไซต์ที่มีหลายไฟล์ HTML จะทำงานอัตโนมัติตามเส้นทางไฟล์ที่แสดงใน URL เช่นไฟล์เหล่านี้ในโปรเจกต์ของคุณ:

mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html

ถ้าคุณสร้างเว็บเซิร์ฟเวอร์โดยมี mywebsite เป็น root, การแมป URL จะเป็น:

https://site.com            --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/     --> mywebsite/admin/index.html

แต่สำหรับเว็บแอปของเรา เราใช้ไฟล์ HTML เดียวที่มีหน้าจอทั้งหมด ดังนั้นพฤติกรรมพื้นฐานนี้จะไม่ช่วย เราต้องสร้างแผนที่นี้เองและอัปเดตเทมเพลตที่แสดงด้วย JavaScript

งานที่ต้องทำ

เราจะใช้วัตถุอย่างง่ายเพื่อทำ map ระหว่างเส้นทาง URL กับเทมเพลตของเรา เพิ่มวัตถุตัวนี้ไว้ด้านบนสุดของไฟล์ app.js

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard' },
};

เข้าใจการตั้งค่าเส้นทางนี้:

  • กำหนด แผนที่ระหว่างเส้นทาง URL กับตัวระบุเทมเพลต
  • ใช้ ไวยากรณ์วัตถุโดยมีคีย์เป็นเส้นทาง URL และค่าระบุข้อมูลเทมเพลต
  • เปิดใช้งาน การค้นหาเทมเพลตที่จะแสดงสำหรับ URL ใดๆ ได้ง่าย
  • มอบโครงสร้างที่ขยายได้เพื่อเพิ่มเส้นทางใหม่ในอนาคต ตอนนี้เรามาปรับฟังก์ชัน updateRoute เล็กน้อย แทนที่จะส่งค่า templateId โดยตรงเป็นอาร์กิวเมนต์ เราต้องการดึงค่าดังกล่าวโดยการดูที่ URL ปัจจุบันก่อน จากนั้นใช้แมปของเราเพื่อรับค่า template ID ที่สอดคล้องกัน เราสามารถใช้ window.location.pathname เพื่อดึงเฉพาะส่วน path ของ URL ได้
function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

อธิบายสิ่งที่เกิดขึ้นที่นี่:

  • ดึงออกมา path ปัจจุบันจาก URL ของเบราว์เซอร์โดยใช้ window.location.pathname
  • ค้นหา การกำหนดเส้นทางที่ตรงกันในออบเจ็กต์ routes ของเรา
  • ดึง template ID จากการกำหนดเส้นทางนั้น
  • ทำตาม กระบวนการแสดงผลเทมเพลตเหมือนเดิม
  • สร้าง ระบบไดนามิกที่ตอบสนองต่อการเปลี่ยนแปลง URL

ที่นี่เราได้แมปเส้นทางที่ประกาศไว้ให้กับเทมเพลตที่ตรงกัน คุณสามารถลองดูว่ามันทำงานถูกต้องโดยการเปลี่ยน URL ด้วยตนเองในเบราว์เซอร์ของคุณ

จะเกิดอะไรขึ้นถ้าคุณป้อน path ที่ไม่รู้จักใน URL? เราจะแก้ปัญหานี้อย่างไร?

การเพิ่มการนำทาง

เมื่อมีการกำหนด routing แล้ว ผู้ใช้จะต้องมีวิธีนำทางผ่านแอป เว็บไซต์แบบดั้งเดิมจะโหลดหน้าทั้งหมดใหม่เมื่อคลิกลิงก์ แต่เราต้องการอัปเดตทั้ง URL และเนื้อหาโดยไม่รีเฟรชหน้า สิ่งนี้จะสร้างประสบการณ์ที่ราบรื่นกว่า คล้ายกับวิธีที่แอปเดสก์ท็อปสลับระหว่างมุมมองต่างๆ

เราต้องประสานสองอย่าง: การอัปเดต URL ของเบราว์เซอร์เพื่อให้ผู้ใช้สามารถบันทึกหน้านี้และแชร์ลิงก์ และการแสดงเนื้อหาที่เหมาะสม เมื่อทำอย่างถูกต้องแล้ว มันจะสร้างการนำทางที่ราบรื่นตามที่ผู้ใช้คาดหวังจากแอปสมัยใหม่

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: คลิกลิงก์ "เข้าสู่ระบบ"
    Browser->>App: เหตุการณ์ onclick ถูกเรียกใช้
    App->>App: preventDefault() & navigate('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: อัปเดต URL เป็น /dashboard
    App->>App: updateRoute() ถูกเรียก
    App->>Template: ค้นหา & คลิ template ของแดชบอร์ด
    Template->>App: ส่งคืนเนื้อหาที่คัดลอก
    App->>Browser: แทนที่เนื้อหาแอปด้วย template
    Browser->>User: แสดงหน้าจอแดชบอร์ด
    
    Note over User,Template: ผู้ใช้คลิกปุ่มย้อนกลับของเบราว์เซอร์
    
    User->>Browser: คลิกปุ่มย้อนกลับ
    Browser->>Browser: ประวัติย้อนกลับไป /login
    Browser->>App: เหตุการณ์ popstate ถูกเรียก
    App->>App: updateRoute() ถูกเรียกโดยอัตโนมัติ
    App->>Template: ค้นหา & คลิ template ของการเข้าสู่ระบบ
    Template->>App: ส่งคืนเนื้อหาที่คัดลอก
    App->>Browser: แทนที่เนื้อหาแอปด้วย template
    Browser->>User: แสดงหน้าจอเข้าสู่ระบบ

🔄 ตรวจสอบความเข้าใจเบื้องต้น

สถาปัตยกรรมแอปแบบหน้าเดียว (SPA): ตรวจสอบความเข้าใจของคุณเกี่ยวกับระบบทั้งหมด:

  • การ routing ที่ฝั่งไคลเอนต์ต่างจาก routing ที่ฝั่งเซิร์ฟเวอร์แบบดั้งเดิมอย่างไร?
  • ทำไม History API จึงสำคัญต่อการนำทางใน SPA อย่างถูกต้อง?
  • เทมเพลตช่วยให้เนื้อหาไดนามิกโดยไม่ต้องรีโหลดหน้าได้อย่างไร?
  • การจัดการเหตุการณ์มีบทบาทอย่างไรในการดักจับการนำทาง?

การบูรณาการระบบ: SPA ของคุณแสดงถึง:

  • การจัดการเทมเพลต: คอมโพเนนต์ UI ที่นำกลับมาใช้ใหม่ได้พร้อมเนื้อหาไดนามิก
  • Routing ฝั่งไคลเอนต์: การจัดการ URL โดยไม่ส่งคำขอไปยังเซิร์ฟเวอร์
  • สถาปัตยกรรมขับเคลื่อนโดยเหตุการณ์: การนำทางและการโต้ตอบกับผู้ใช้ที่ตอบสนอง
  • การบูรณาการกับเบราว์เซอร์: ประวัติ และปุ่มย้อนกลับ/ไปข้างหน้าที่ทำงานอย่างถูกต้อง
  • การเพิ่มประสิทธิภาพ: การเปลี่ยนผ่านที่รวดเร็วและลดภาระเซิร์ฟเวอร์

รูปแบบมืออาชีพ: คุณได้ใช้งาน:

  • การแยกโมเดล-วิว: เทมเพลตแยกจากตรรกะแอปพลิเคชัน
  • การจัดการสถานะ: สถานะ URL ซิงโครไนซ์กับเนื้อหาที่แสดง
  • การยกระดับแบบก้าวหน้า: JavaScript ช่วยเพิ่มฟังก์ชัน HTML พื้นฐาน
  • ประสบการณ์ผู้ใช้: การนำทางที่ราบรื่นเหมือนแอปโดยไม่รีเฟรชหน้า

<EFBFBD> ความเข้าใจด้านสถาปัตยกรรม: องค์ประกอบของระบบนำทาง

สิ่งที่คุณกำลังสร้าง:

  • 🔄 การจัดการ URL: อัปเดตแถบที่อยู่ของเบราว์เซอร์โดยไม่รีโหลดหน้า
  • 📋 ระบบเทมเพลต: สลับเนื้อหาแบบไดนามิกตามเส้นทางปัจจุบัน
  • 📚 การบูรณาการประวัติ: รักษาการทำงานของปุ่มย้อนกลับ/ไปข้างหน้า
  • 🛡️ การจัดการข้อผิดพลาด: กลไก fallback อย่างสมเหตุสมผลสำหรับเส้นทางที่ไม่ถูกต้องหรือขาดหาย

วิธีที่องค์ประกอบทำงานร่วมกัน:

  • ฟัง เหตุการณ์นำทาง (คลิก, การเปลี่ยนแปลงประวัติ)
  • อัปเดต URL โดยใช้ History API
  • เรนเดอร์ เทมเพลตที่เหมาะสมสำหรับเส้นทางใหม่
  • รักษา ประสบการณ์ผู้ใช้ที่ราบรื่นตลอดเวลา

ขั้นตอนถัดไปสำหรับแอปของเราคือเพิ่มความสามารถในการนำทางระหว่างหน้าโดยไม่ต้องเปลี่ยน URL ด้วยตนเอง นี่หมายถึงสองอย่าง:

  1. อัปเดต URL ปัจจุบัน
  2. อัปเดตเทมเพลตที่แสดงตาม URL ใหม่

เราได้ดูแลส่วนที่สองไว้แล้วด้วยฟังก์ชัน updateRoute ดังนั้นเราต้องหาวิธีอัปเดต URL ปัจจุบัน

เราจะต้องใช้ JavaScript และโดยเฉพาะ history.pushState ที่อนุญาตให้อัปเดต URL และสร้างรายการใหม่ในประวัติการเข้าชมโดยไม่รีโหลด HTML

⚠️ หมายเหตุสำคัญ: แม้ว่าองค์ประกอบแองเคอร์ HTML <a href> สามารถใช้เพื่อสร้างลิงก์ไปยัง URL ต่างๆ ได้ แต่มันจะทำให้เบราว์เซอร์รีโหลด HTML โดยค่าเริ่มต้น จำเป็นต้องป้องกันพฤติกรรมนี้เมื่อต้องจัดการ routing ด้วย JavaScript แบบกำหนดเอง โดยใช้ฟังก์ชัน preventDefault() กับเหตุการณ์คลิก

ภารกิจ

มาสร้างฟังก์ชันใหม่ที่เราสามารถใช้เพื่อการนำทางในแอปของเรากัน:

function navigate(path) {
  window.history.pushState({}, path, path);
  updateRoute();
}

ทำความเข้าใจฟังก์ชันนำทางนี้:

  • อัปเดต URL ของเบราว์เซอร์เป็น path ใหม่โดยใช้ history.pushState
  • เพิ่ม รายการใหม่ลงในสแตกของประวัติการเข้าชมเพื่อรองรับปุ่มย้อนกลับ/ไปข้างหน้าอย่างเหมาะสม
  • เรียก ฟังก์ชัน updateRoute() เพื่อแสดงเทมเพลตที่สอดคล้องกัน
  • รักษา ประสบการณ์แอปหน้าเดียวโดยไม่มีการรีโหลดหน้า

วิธีนี้จะอัปเดต URL ปัจจุบันตาม path ที่กำหนดก่อน จากนั้นอัปเดตเทมเพลต คุณสมบัติ window.location.origin คืนค่า URL ราก ทำให้เราสามารถสร้าง URL สมบูรณ์จาก path ที่กำหนดได้

เมื่อเรามีฟังก์ชันนี้แล้ว เราสามารถแก้ปัญหาที่เกิดขึ้นถ้า path ไม่ตรงกับเส้นทางที่กำหนดไว้ เราจะปรับฟังก์ชัน updateRoute โดยเพิ่มการ fallback ไปยังเส้นทางที่มีอยู่ถ้าไม่พบการจับคู่

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  if (!route) {
    return navigate('/login');
  }

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

จุดสำคัญที่ต้องจำ:

  • ตรวจสอบ ว่ามีเส้นทางสำหรับ path ปัจจุบันหรือไม่
  • เปลี่ยนทาง ไปยังหน้าล็อกอินเมื่อเข้าถึงเส้นทางที่ไม่ถูกต้อง
  • จัดเตรียม กลไก fallback ที่ป้องกันการนำทางที่ผิดพลาด
  • รับประกัน ว่าผู้ใช้จะเห็นหน้าจอที่ถูกต้องเสมอ แม้ URL จะไม่ถูกต้อง

ถ้าไม่พบเส้นทาง เราจะเปลี่ยนเส้นทางไปหน้าล็อกอินแทน

ตอนนี้มาสร้างฟังก์ชันเพื่อดึง URL เมื่อมีการคลิกลิงก์ และเพื่อป้องกันพฤติกรรมลิงก์ปกติของเบราว์เซอร์:

function onLinkClick(event) {
  event.preventDefault();
  navigate(event.target.href);
}

อธิบายตัวจัดการคลิกนี้:

  • ป้องกัน พฤติกรรมลิงก์ปกติของเบราว์เซอร์โดยใช้ preventDefault()
  • ดึงออกมา URL ปลายทางจากองค์ประกอบลิงก์ที่ถูกคลิก
  • เรียก ฟังก์ชันนำทางที่กำหนดเองแทนการโหลดหน้าซ้ำ
  • รักษา ประสบการณ์แอปหน้าเดียวที่ราบรื่น
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>

สิ่งที่ผูกเหตุการณ์ onclick นี้ทำได้:

  • เชื่อม ลิงก์แต่ละอันกับระบบนำทางที่กำหนดเองของเรา
  • ส่งผ่าน เหตุการณ์คลิกไปที่ฟังก์ชัน onLinkClick ของเราเพื่อนำไปประมวลผล
  • เปิดใช้งาน การนำทางที่ราบรื่นโดยไม่มีการโหลดหน้า
  • รักษา โครงสร้าง URL ที่ถูกต้อง ซึ่งผู้ใช้สามารถบันทึกหรือแชร์ได้

แอตทริบิวต์ onclick ผูกเหตุการณ์ click กับโค้ด JavaScript ที่นี่คือการเรียก navigate() ฟังก์ชัน

ลองคลิกที่ลิงก์เหล่านี้ คุณจะสามารถนำทางระหว่างหน้าจอในแอปของคุณได้

เมธอด history.pushState เป็นส่วนหนึ่งของมาตรฐาน HTML5 และใช้ได้ใน เบราว์เซอร์สมัยใหม่ทุกตัว หากคุณกำลังสร้างเว็บแอปสำหรับเบราว์เซอร์เก่า มีเทคนิคที่คุณสามารถใช้แทน API นี้ได้: ใช้ แฮช (#) นำหน้าทางเดินเพื่อทำ routing ที่ทำงานกับการนำทางแองเคอร์ปกติและไม่โหลดหน้าใหม่ เนื่องจากจุดประสงค์เดิมคือการสร้างลิงก์ภายในหน้า

ทำให้ปุ่มย้อนกลับและไปข้างหน้าทำงาน

ปุ่มย้อนกลับและไปข้างหน้าเป็นสิ่งสำคัญในการท่องเว็บ เหมือนกับที่เจ้าหน้าที่ควบคุมภารกิจของนาซาสามารถตรวจสอบสถานะระบบก่อนหน้าระหว่างภารกิจในอวกาศได้ ผู้ใช้คาดหวังว่าปุ่มเหล่านี้จะทำงาน และเมื่อไม่ทำงาน จะทำลายประสบการณ์การท่องเว็บที่คาดหวัง

แอปหน้าเดียวของเราต้องการการกำหนดค่าเพิ่มเติมเพื่อรองรับสิ่งนี้ เบราว์เซอร์จะเก็บสแตกประวัติ (ซึ่งเราได้เพิ่มเข้าไปด้วย history.pushState) แต่เมื่อผู้ใช้เดินทางผ่านประวัตินี้ แอปของเราต้องตอบสนองโดยการอัปเดตเนื้อหาที่แสดงตามนั้น

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: คลิกที่ลิงก์ "เข้าสู่ระบบ"
    Browser->>App: เหตุการณ์ onclick ถูกเรียกใช้
    App->>App: preventDefault() & navigate('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL อัปเดตเป็น /dashboard
    App->>App: updateRoute() ถูกเรียก
    App->>Template: ค้นหา & คัดลอกเทมเพลตแดชบอร์ด
    Template->>App: ส่งคืนเนื้อหาที่คัดลอกแล้ว
    App->>Browser: แทนที่เนื้อหาแอปด้วยเทมเพลต
    Browser->>User: แสดงหน้าจอแดชบอร์ด
    
    Note over User,Template: ผู้ใช้คลิ๊กปุ่มย้อนกลับของเบราว์เซอร์
    
    User->>Browser: คลิกปุ่มย้อนกลับ
    Browser->>Browser: ประวัติย้อนกลับไปที่ /login
    Browser->>App: เหตุการณ์ popstate ถูกเรียกใช้
    App->>App: updateRoute() ถูกเรียกโดยอัตโนมัติ
    App->>Template: ค้นหา & คัดลอกเทมเพลตเข้าสู่ระบบ
    Template->>App: ส่งคืนเนื้อหาที่คัดลอกแล้ว
    App->>Browser: แทนที่เนื้อหาแอปด้วยเทมเพลต
    Browser->>User: แสดงหน้าจอเข้าสู่ระบบ

จุดที่มีการปฏิสัมพันธ์หลัก:

  • การกระทำของผู้ใช้ กระตุ้นการนำทางผ่านการคลิกหรือปุ่มของเบราว์เซอร์
  • แอปดักจับ การคลิกลิงก์เพื่อป้องกันการโหลดหน้าใหม่
  • History API จัดการการเปลี่ยนแปลง URL และสแตกประวัติของเบราว์เซอร์
  • เทมเพลต ให้โครงสร้างเนื้อหาสำหรับแต่ละหน้าจอ
  • ตัวฟังเหตุการณ์ ทำให้แน่ใจว่าแอปตอบสนองต่อทุกประเภทของการนำทาง

การใช้ history.pushState สร้างรายการใหม่ในประวัติการนำทางของเบราว์เซอร์ คุณสามารถตรวจสอบได้โดยการกดปุ่ม ย้อนกลับ ค้างไว้ เบราว์เซอร์จะแสดงประวัติประมาณนี้:

Screenshot of navigation history

ถ้าคุณลองกดปุ่มย้อนกลับหลายครั้ง คุณจะเห็นว่า URL ปัจจุบันเปลี่ยนและประวัติได้รับการอัปเดต แต่เทมเพลตเดิมยังคงแสดงอยู่

นั่นเป็นเพราะแอปไม่รู้ว่าเราต้องเรียก updateRoute() ทุกครั้งที่ประวัติเปลี่ยน หากคุณดูที่เอกสาร history.pushState คุณจะเห็นว่าถ้าสถานะเปลี่ยน—หมายความว่าเราไปยัง URL ใหม่—จะมีเหตุการณ์ popstate ถูกเรียก เราจะใช้สิ่งนี้เพื่อแก้ปัญหานี้

ภารกิจ

เพื่อให้แน่ใจว่าเทมเพลตที่แสดงได้รับการอัปเดตเมื่อประวัติของเบราว์เซอร์เปลี่ยนไป เราจะผูกฟังก์ชันใหม่ที่เรียก updateRoute() เราจะทำที่ด้านล่างของไฟล์ app.js ของเรา:

window.onpopstate = () => updateRoute();
updateRoute();

เข้าใจการบูรณาการประวัตินี้:

  • ฟัง เหตุการณ์ popstate ที่เกิดเมื่อผู้ใช้ใช้งานปุ่มเบราว์เซอร์
  • ใช้ ฟังก์ชันลูกศรเพื่อความกระชับของไวยากรณ์ผู้จัดการเหตุการณ์
  • เรียก updateRoute() โดยอัตโนมัติเมื่อสถานะประวัติเปลี่ยน
  • เริ่มต้น แอปโดยเรียก updateRoute() เมื่อหน้าโหลดครั้งแรก
  • รับประกัน เทมเพลตที่ถูกต้องแสดงไม่ว่าใช้วิธีนำทางใด

💡 เคล็ดลับมือโปร: เราใช้ ฟังก์ชันลูกศร ที่นี่เพื่อประกาศผู้จัดการเหตุการณ์ popstate เพื่อความกระชับ แต่ฟังก์ชันปกติก็สามารถทำงานได้เช่นกัน

นี่คือวิดีโอทบทวนเรื่องฟังก์ชันลูกศร:

Arrow Functions

🎥 คลิกภาพด้านบนเพื่อดูวิดีโอเกี่ยวกับฟังก์ชันลูกศร

ทดลองใช้งานปุ่มย้อนกลับและไปข้างหน้าของเบราว์เซอร์ แล้วตรวจสอบว่าเส้นทางที่แสดงได้รับการอัปเดตอย่างถูกต้องในครั้งนี้

สิ่งที่คุณสามารถทำได้ใน 5 นาทีถัดไป

  • ทดสอบการนำทางของแอปธนาคารโดยใช้ปุ่มย้อนกลับ/ไปข้างหน้าในเบราว์เซอร์
  • พยายามพิมพ์ URL ต่างๆ ในแถบที่อยู่เพื่อลองเส้นทาง
  • เปิด DevTools ของเบราว์เซอร์และตรวจสอบว่าเทมเพลตถูกโคลนเข้า DOM อย่างไร
  • ทดลองเพิ่มคำสั่ง console.log เพื่อติดตามกระแสการ routing

🎯 สิ่งที่คุณสามารถทำได้ในชั่วโมงนี้

  • ทำแบบทดสอบหลังบทเรียนให้เสร็จและเข้าใจแนวคิดสถาปัตยกรรม SPA
  • เพิ่มการจัดสไตล์ CSS เพื่อทำให้เทมเพลตของแอปธนาคารดูมืออาชีพ
  • ทำโจทย์หน้าข้อผิดพลาด 404 พร้อมจัดการข้อผิดพลาดอย่างเหมาะสม
  • สร้างหน้าเครดิตพร้อมเพิ่มฟังก์ชัน routing
  • เพิ่มสถานะการโหลดและการเปลี่ยนผ่านระหว่างการสลับเทมเพลต

📅 เส้นทางพัฒนาการ SPA 1 สัปดาห์ของคุณ

  • พัฒนาแอปธนาคารเต็มรูปแบบพร้อมแบบฟอร์ม การจัดการข้อมูล และการเก็บข้อมูลถาวร
  • เพิ่มฟีเจอร์ routing ขั้นสูง เช่น พารามิเตอร์เส้นทาง และเส้นทางซ้อน
  • ทำหน้าที่ควบคุมการนำทางและ routing โดยยืนยันตัวตน
  • สร้างคอมโพเนนต์เทมเพลตที่นำกลับมาใช้ได้และไลบรารีคอมโพเนนต์
  • เพิ่มแอนิเมชันและการเปลี่ยนผ่านเพื่อประสบการณ์ที่ราบรื่นขึ้น
  • ดีพลอยแอป SPA ของคุณบนแพลตฟอร์มโฮสติ้งและกำหนด routing อย่างถูกต้อง

🌟 การเป็นผู้เชี่ยวชาญสถาปัตยกรรม frontend 1 เดือนของคุณ

  • สร้าง SPA ที่ซับซ้อนโดยใช้เฟรมเวิร์กสมัยใหม่เช่น React, Vue, หรือ Angular
  • เรียนรู้รูปแบบการจัดการสถานะขั้นสูงและไลบรารีต่างๆ
  • เชี่ยวชาญเครื่องมือบิวด์และเวิร์กโฟลว์การพัฒนา SPA
  • ทำ Progressive Web App และฟีเจอร์ทำงานแบบออฟไลน์
  • ศึกษาเทคนิคเพิ่มประสิทธิภาพสำหรับ SPA ขนาดใหญ่
  • มีส่วนร่วมในโครงการ SPA แบบโอเพนซอร์สและแบ่งปันความรู้ของคุณ

🎯 เส้นเวลาการเป็นผู้เชี่ยวชาญแอปหน้าเดียวของคุณ

timeline
    title ความก้าวหน้าในการเรียนรู้การพัฒนา SPA และสถาปัตยกรรมเว็บสมัยใหม่
    
    section พื้นฐาน (20 นาที)
        Template Systems: องค์ประกอบแม่แบบ HTML
                        : การจัดการ DOM
                        : การโคลนเนื้อหา
                        : การแสดงผลแบบไดนามิก
        
    section พื้นฐานการเส้นทาง (30 นาที)
        Client-side Navigation: การจัดการ URL
                              : History API
                              : การจัดแมปเส้นทาง
                              : การจัดการเหตุการณ์
        
    section ประสบการณ์ผู้ใช้ (40 นาที)
        Navigation Polish: การรวมเบราว์เซอร์
                         : การสนับสนุนปุ่มย้อนกลับ
                         : การจัดการข้อผิดพลาด
                         : การเปลี่ยนผ่านที่ราบรื่น
        
    section รูปแบบสถาปัตยกรรม (50 นาที)
        Professional SPAs: ระบบคอมโพเนนต์
                         : การจัดการสถานะ
                         : การปรับปรุงประสิทธิภาพ
                         : ขอบเขตข้อผิดพลาด
        
    section เทคนิคขั้นสูง (1 สัปดาห์)
        Framework Integration: React Router
                             : Vue Router
                             : Angular Router
                             : ไลบรารีสถานะ
        
    section ทักษะการผลิต (1 เดือน)
        Enterprise Development: ระบบการสร้าง
                              : กลยุทธ์การทดสอบ
                              : สายการปรับใช้
                              : การติดตามประสิทธิภาพ

🛠️ สรุปชุดเครื่องมือพัฒนา SPA ของคุณ

หลังจากจบบทเรียนนี้ คุณได้เชี่ยวชาญ:

  • สถาปัตยกรรมเทมเพลต: คอมโพเนนต์ HTML ที่นำกลับมาใช้ใหม่พร้อมการเรนเดอร์เนื้อหาไดนามิก
  • Routing ฝั่งไคลเอนต์: การจัดการ URL และการนำทางโดยไม่รีโหลดหน้า
  • การบูรณาการกับเบราว์เซอร์: การใช้ History API และรองรับปุ่มย้อนกลับ/ไปข้างหน้า
  • ระบบขับเคลื่อนด้วยเหตุการณ์: จัดการการนำทางและการโต้ตอบกับผู้ใช้
  • การจัดการ DOM: การโคลนเทมเพลต การสลับเนื้อหา และการจัดการองค์ประกอบ
  • การจัดการข้อผิดพลาด: ระบบ fallback อย่างสมเหตุสมผลสำหรับเส้นทางไม่ถูกต้องและเนื้อหาขาดหาย
  • รูปแบบประสิทธิภาพ: กลยุทธ์การโหลดและเรนเดอร์เนื้อหาอย่างมีประสิทธิภาพ

แอปพลิเคชันในโลกจริง: ทักษะการพัฒนา SPA ของคุณใช้ได้โดยตรงกับ:

  • เว็บแอปสมัยใหม่: การพัฒนา React, Vue, Angular และเฟรมเวิร์กอื่นๆ
  • แอปเว็บก้าวหน้า (PWA): แอปใช้งานแบบออฟไลน์พร้อมประสบการณ์เหมือนแอป
  • แดชบอร์ดองค์กร: แอปธุรกิจซับซ้อนพร้อมมุมมองหลายแบบ
  • แพลตฟอร์มอีคอมเมิร์ซ: แคตตาล็อกสินค้า รถเข็น และขั้นตอนจ่ายเงิน
  • การจัดการเนื้อหา: การสร้างเนื้อหาไดนามิกและอินเทอร์เฟซแก้ไข
  • พัฒนาโมบาย: แอปไฮบริดใช้เทคโนโลยีเว็บ

ทักษะมืออาชีพที่ได้รับ: คุณสามารถ...

  • ออกแบบสถาปัตยกรรม แอปพลิเคชันหน้าเดียวด้วยการแยกความรับผิดชอบอย่างเหมาะสม
  • ติดตั้งใช้งาน ระบบ routing ฝั่งไคลเอนต์ที่สามารถขยายได้ตามความซับซ้อนของแอป
  • ดีบัก โฟลว์การนำทางที่ซับซ้อนโดยใช้เครื่องมือสำหรับนักพัฒนาเบราว์เซอร์
  • ปรับปรุง ประสิทธิภาพของแอปพลิเคชันผ่านการจัดการเทมเพลตอย่างมีประสิทธิภาพ
  • ออกแบบ ประสบการณ์ผู้ใช้ที่ให้ความรู้สึกเหมือนแอปเนทีฟและตอบสนองได้เร็ว

แนวคิดการพัฒนาด้าน Frontend ที่เชี่ยวชาญ:

  • สถาปัตยกรรมคอมโพเนนต์: รูปแบบ UI ที่ใช้ซ้ำได้และระบบเทมเพลต
  • การซิงโครไนซ์สถานะ: การจัดการสถานะ URL และประวัติของเบราว์เซอร์
  • โปรแกรมแบบขับเคลื่อนด้วยเหตุการณ์: การจัดการปฏิสัมพันธ์ของผู้ใช้และการนำทาง
  • การปรับแต่งประสิทธิภาพ: การจัดการ DOM อย่างมีประสิทธิภาพและการโหลดเนื้อหา
  • การออกแบบประสบการณ์ผู้ใช้: การเปลี่ยนระหว่างหน้าอย่างราบรื่นและการนำทางที่ใช้งานง่าย

ก้าวต่อไป: คุณพร้อมที่จะสำรวจเฟรมเวิร์ก frontend สมัยใหม่, การจัดการสถานะขั้นสูง หรือสร้างแอปพลิเคชันระดับองค์กรที่ซับซ้อน!

🌟 ความสำเร็จที่ปลดล็อก: คุณได้สร้างฐานแอปพลิเคชันหน้าเดียวระดับมืออาชีพด้วยรูปแบบสถาปัตยกรรมเว็บสมัยใหม่แล้ว!


ความท้าทาย GitHub Copilot Agent 🚀

ใช้โหมด Agent เพื่อทำความท้าทายดังต่อไปนี้:

คำอธิบาย: ปรับปรุงแอปธนาคารโดยเพิ่มการจัดการข้อผิดพลาดและเทมเพลตหน้า 404 สำหรับเส้นทางที่ไม่ถูกต้อง เพื่อพัฒนาประสบการณ์ผู้ใช้เมื่อไปยังหน้าที่ไม่มีอยู่จริง

คำสั่ง: สร้างเทมเพลต HTML ใหม่โดยมี id ว่า "not-found" เพื่อแสดงหน้าข้อผิดพลาด 404 ที่เป็นมิตรกับผู้ใช้พร้อมสไตล์ จากนั้นแก้ไขตรรกะ routing ใน JavaScript เพื่อแสดงเทมเพลตนี้เมื่อผู้ใช้ไปยัง URL ที่ไม่ถูกต้อง และเพิ่มปุ่ม "Go Home" ที่นำทางกลับไปยังหน้าล็อกอิน

เรียนรู้เพิ่มเติมเกี่ยวกับ agent mode ที่นี่

🚀 ความท้าทาย

เพิ่มเทมเพลตและเส้นทางใหม่สำหรับหน้าที่สามซึ่งแสดงเครดิตของแอปนี้

เป้าหมายของความท้าทาย:

  • สร้าง เทมเพลต HTML ใหม่ที่มีโครงสร้างเนื้อหาที่เหมาะสม
  • เพิ่ม เส้นทางใหม่ในอ็อบเจ็กต์การตั้งค่า routes ของคุณ
  • รวม ลิงก์นำทางไปและกลับจากหน้าคะแนน
  • ทดสอบ ว่าการนำทางทั้งหมดทำงานถูกต้องกับประวัติของเบราว์เซอร์

แบบทดสอบหลังบรรยาย

แบบทดสอบหลังบรรยาย

ทบทวน & ศึกษาด้วยตนเอง

Routing เป็นส่วนที่ค่อยข้างซับซ้อนในการพัฒนาเว็บโดยเฉพาะเมื่อเว็บเปลี่ยนจากพฤติกรรมรีเฟรชหน้าแบบดั้งเดิมไปสู่การรีเฟรชหน้าในแอปหน้าเดียว อ่านเพิ่มเติมเกี่ยวกับ วิธีที่ Azure Static Web App service จัดการ routing คุณสามารถอธิบายได้ไหมว่าทำไมบางการตัดสินใจที่อธิบายในเอกสารนั้นจึงจำเป็น?

แหล่งเรียนรู้เพิ่มเติม:

  • สำรวจ วิธีที่เฟรมเวิร์กยอดนิยม เช่น React Router และ Vue Router ใช้ routing ฝั่งไคลเอนต์
  • ค้นคว้า ความแตกต่างระหว่าง routing แบบ hash-based กับ history API
  • เรียนรู้ เกี่ยวกับการเรนเดอร์ฝั่งเซิร์ฟเวอร์ (SSR) และผลกระทบต่อกลยุทธ์ routing
  • สืบสวน วิธีที่ Progressive Web Apps (PWAs) จัดการ routing และการนำทาง

การบ้าน

ปรับปรุงการ routing


ข้อจำกัดความรับผิดชอบ: เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษาโดย AI Co-op Translator แม้เราจะพยายามให้ความถูกต้องสูงสุด แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาต้นทางควรถือเป็นแหล่งข้อมูลที่เป็นทางการ สำหรับข้อมูลที่สำคัญแนะนำให้ใช้บริการแปลโดยผู้เชี่ยวชาญมนุษย์ เราจะไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดใดๆ ที่เกิดขึ้นจากการใช้การแปลนี้