มือใหม่ Nuxt.js + TypeScript pt.4 SImple Todo List Walkthrough

แนวทางการพัฒนาเว็บแอปพลิเคชั่นด้วย Nuxt.js + Typescript สำหรับมือใหม่

สวัสดีครับ หลังจากเราได้ทราบ concept การใช้ nuxt.js ร่วมกับ type script กันมาบ้างแล้ว ถึงเวลาที่เราจะเริ่มลองนำมาใช้งานจริงกันครับ วันนี้เราจะมาทำ Todo List ง่าย ๆ กันครับ

Todo list ของเราจะทำอะไรได้บ้าง?

  1. เพิ่ม todo ได้

  2. แก้ไข todo ได้

  3. ลบ todo ได้

  4. เก็บ todo list ของเราไว้ใน local storage

  5. done ให้กับ todo ได้

  6. undone ให้กับ todo ได้

  7. มีบอร์ดแสดงค่า total todo, total done todo และ total undone todo

  8. มี List แสดง todo และสามารถเลือกที่จะแสดงแค่ done todo หรือ undone todo ได้

Design todo จาก requirement

หลังจากเราได้ requirement มาเราก็ใช้ figma design ออกมาได้ประมาณนี้ครับ

Simple todolist design by mnagon

⚠️ ผมขอข้ามขั้นตอนการสร้าง nuxt project และการติดตั้ง module ต่าง ๆ นะครับ หากใครยังไม่ทราบว่าต้องติดตั้งหรือใช้งานอะไรบ้าง แนะนำให้กลับไปอ่านบทก่อนหน้าได้ครับ

แยก Component

เราจะพิจารณาจาก design ของเราครับว่า จะสามารถแยก component อะไรบ้าง ซึ้งจาก design ที่ผมทำไว้ผมแยก component ออกมาได้แบบนี้ครับ

Todo list component
  1. Navbar (Navbar)

  2. Scoreboard (Board)

  3. Todo input box (TodoInput)

  4. Todo card (TodoItem)

จะเห็นได้ว่าเราแยกออกมาได้เป็น 4 component ครับ ให้เราทำการสร้างไฟล์ Navbar.vue, Board.vue, TodoInput.vue และสุดท้าย TodoItem.vue ที่ folder components ครับ

ให้เรา style ตัว component ออกมาให้เหมือน design ของเราที่สุดได้เลยครับ ผมไม่ขอลงรายละเอียดของ template และ style นะครับ เดียวมันจะเยอะเกิน แต่ว่าหากใครที่ขี้เกียจเขียน template และ style เอง ผมมี project starter ที่ผมทำเสร็จแล้วมาแจกครับเป็นตัวที่มีแค่ส่วนของ template และ style พร้อมที่จะเข้าสู่การเขียน script เลยครับ

Download project stater >> https://github.com/mnagon/nuxt-typescript-todolist-starter

เริ่มจาก Store กันก่อน

ให้เราติดตั้ง module nuxt-typed-vuex ให้เรียบร้อยก่อนนะครับ หลังจากนั้นสร้างไฟล์ index.ts ใน folder store กันเลยครับ

State

State ของ todo list ก็ไม่มีอะไรมากเลยครับก็มีแค่ array ของ todo เท่านั้นเองครับ ส่วน todo ของเราก็เป็น object ที่มี string และ boolean อย่างหละตัวเพื่อเก็บ todo text และ สถานะว่า done หรือ undone เราก็จะเริ่มจากการสร้าง interface ให้ todo และ state ได้ออกมาแบบนี้ครับ

Getters

ส่วนของ getters เราจะทำ getters ไว้สองตัวครับคือ doneTodo และ undoneTodo เพื่อเวลาเรา filter done หรือ undone todo เราสามารถมาเอา todo list ได้จาก getters สองตัวนี้ครับ (* อย่าลืม import getterTree ด้วยนะครับ)

Mutations

เราจะทำ store ของเราให้ครบในส่วนของ CRUD เลยครับ เพียงแต่ว่า read เราใช้ส่วนของ state และ getters ไปแล้ว เพราะฉนั้น mutations ของเราต้องมี create, update และ delete ครับ เหมือนตัวอย่างด้านล่างเลย (*อย่าลืม import mutationTree ด้วยนะครับ)

จะเห็นได้ว่าในส่วนของ UPDATE_TODO ของผม ผมต้องการ payload ที่เป็น object ที่มี todo และ index ของ todo ที่ต้องการอัปเดท ซึ้งเราก็ควรเขียน type ให้กับ payload ตัวนี้ด้วย เพื่อป้องกันการส่งผ่านค่า payload ที่ผิดพลาดเข้ามาได้ครับ ผมจึงแอบไปสร้าง interface สำหรับ UpdateTodoPayload เข้ามาเหมือนในตัวอย่างครับ

Actions

สำหรับ actions ช่วงแรก็ไม่มีอะไรมากครับ ทำ actions ให้ครอบคลุมทั้ง mutations ของเราไปก่อนเหมือนตัวอย่างด่านล้างครับ (* อย่าลืม import actionTree นะครับ)

อย่าลืมประกาศ $accessor

สุดท้าย export accessorType และ อย่าลืมสร้างไฟล์ index.d.ts และประกาศ $accessor ด้วยครับ ใครที่ไม่รู้ว่าคืออะไรสามารถย้อนกลับไปดูที่ pt.3 ได้ครับ

ทำงานกับ Localstorage

เพื่อเก็บ todo list ของเราไว้ใน local storage เราจะมาอัปเดท store ของเราให้ทำงานร่วมกับ localstorage กันครับ โดยผมได้สร้าง action ชื่อว่า updateStorage เพื่อเก็บ todo list ของเราไว้ใน localstorage แล้วหลังจากนั้นผมจะเรียกใช้ action นี้ทุกครั้งที่มีการ create, update หรือ delete todo เหมือนตัวอย่างด้านล่างเลยครับ

ไม่เพียงเท่านั้นครับ เราก็ต้องมีส่วนของการ get localstorage มาใช้ด้วย เราก็จะเพิ่ม action และ mutation เหมือนตัวอย่างนี้เลยครับ

Set current tab?

จาก design จะเห็นได้ว่าเรามี navbar ที่จะเลือกโชว์ todo list ในแบบต่าง ๆ ด้วย ในขณะที่เรากระทำกับ navbar แต่ส่งผลมาถึง todo item list ข้าม componet แบบนี้ ผมจึงเอามาจัดการใน store ด้วยครับ โดยเพิ่ม current tab เข้าไปใน state แล้วเพิ่ม mutation และ action จัดการเอาไว้ด้วย เหมือนตัวอย่างนี้ครับ

เพียงเท่านี้ก็เสร็จสิ้นการจัดเตรียม store ของเราในรูปแบบ typescript แล้วครับ

จัดการกับ Component

ต่อไปเราจะมาใช้งาน store ของเราในแต่หละ component ครับ โดยจะเรียงตามลำดับกันเลยครับ

Navbar ของเราไม่มีอะไรมากครับ เพียงแค่เรากดตรง tab ไหนเราก็เรียกใช้ action setTab นั้นและเราก็เพิ่ม class active ให้กับ tab นั้นเมื่อ currenTab ตรงกับ ตัวเอง เหมือนตัวอย่างนี้ครับ

Board.vue

ส่วนของ Board ยิ่งง่ายไปกันใหญ่ครับ เพียงแค่เราเข้าถึง state หรือ getters นั้น ๆ แล้ว .length ออกมาเพื่อเป็นค่า totol แค่นั้นเองครับ ไปดูตัวอย่างกันเลยครับ

TodoInput.vue

ในส่วนของ Input ก็ไม่มีอะไรซับซ้อนมากครับ เพียงเรามี input หนึ่งตัว และหลังจากกดปุ่ม add หรือ enter ก็ให้เรียกใช้ method addTodo เพื่อส่งค่าที่ป้อนไปกับ actions addTodo อีกที แค่นี้เองครับ ลองไปดูตัวอย่างกันเลย

Index.vue

ก่อนที่เราจะเริ่มในส่วนของ TodoItem.vue เราต้องมาจัดการข้อมูล todo list ของเราในหน้า index ก่อนครับ ทุกครั้งที่เริ่มโหลดหน้า Index ขึ้นมาเราต้อง get todo มาจาก localstorage เพื่อเซ็ตให้กับ store ของเราก่อน อีกทั้งเรายังต้องแสดง todo list ให้สอดคล้องกับ tab ใน navbar ที่เราได้เลือกไว้อีกด้วยครับ อีกทั้งหน้า index นี้แหละที่เราจะประกอบ Navbar, Board, TodoInput และ TodoItem เข้าด้วยกัน เรามาดูตัวอย่างด้านล่างกันเลยครับ

จะเห็นได้ว่า todoList ที่ผมนำมาวนลูป todo-item นั้นผมได้ประกาศเป็น computed ที่ return ค่าให้สอดคล้องกับ current tab นั้นเองครับ (*สำหรับใครที่งงโค้ดตรงนี้นะครับ มันเป็น if-else ธรรมดาๆ เลยครับเพียงแค่ผมเขียนในรูปแบบ shorthand แค่นั้นเอง)

TodoItem.vue

มาถึง component สุดท้ายของเรานะครับ ตัวนี้พิเศษหน่อยเพราะว่าการ set done, edit todo และ delete todo จะอยู่ที่ component นี้หมดเลย อาจมีลูกเล่นในการทำ edit mode และมีการเปลี่ยนแปลง style จากสถานะ done หรือ undone อยู่ด้วย แต่ action ส่วนใหญ่เราได้สร้างและเตรียมไว้ใน store เรียบร้อยแล้ว ก็แค่จับมาใช้งานให้ครบเท่านั้นเองครับ มาดูโค้ดตัวอย่างกันดีกว่า

เพียงเท่านี้ก็เสร็จเรียบร้อยแล้วครับสำหรับ simple todo list ของเรา 🎉

ซึ้งใครอยากเห็นตัวเต็มของโค้ดที่สำเร็จแล้วทั้งหมดสามารถดูได้จาก repo นี้เลยครับ https://github.com/mnagon/nuxt-typescript-todolist

หลังจากที่เราได้เข้าใจ concept ของ nuxt + typescript จวบจนนำมาสร้าง project เล็ก ๆ กันได้เรียบร้อยแล้วผมก็ขอจบ series nuxt.js + typescript ไว้แค่เพียงเท่านี้ครับ การใช้งานที่ advance หรือ trip trick ผมจะทำอีกบทไว้โดยเฉพาะ และจะอัปเดทเรื่อย ๆ อีกทีครับ สุดท้ายแล้วหากมีข้อผิดพลาดประการใดขออภัยมา ณ ที่นี้ด้วยนะครับ ขอบคุณที่อ่านกันจนจบ series นะครับ 🙏

Last updated

Was this helpful?