การกำหนด key สำหรับการเรนเดอร์ลิสรายการ ใน VueJS

บทความใหม่ ปีนี้ โดย Ninenik Narkdee
vuejs key property array mutation

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ vuejs key property array mutation

ดูแล้ว 668 ครั้ง


ในตอนที่แล้วเราดูเกี่ยวกับการใช้งาน v-for directive สำหรับแสดง
รายการข้อมูลในรูปแบบการวนลูปมาแสดง หรือลิสรายการ เบื้องต้นไปแล้ว
เราจะมาต่อในส่วนของการใช้งานเพิ่มเติมอีกเล็กน้อย 
 

การกำหนด key สำหรับการเรนเดอร์ลิสรายการด้วย v-for ใน VueJS

ใน Vue.js มีสองวิธีหลักในการอัพเดต DOM เมื่อข้อมูลหรือสถานะของแอปเปลี่ยนไป: 
คือวิธ๊การ patching (การแพทช์) และ replacing (การแทนที่). ความแตกต่างระหว่าง
ทั้งสองนี้มีผลกระทบสำคัญต่อประสิทธิภาพและการจัดการสถานะของแอปพลิเคชัน
 

Patching (การแพทช์)

Patching คือกระบวนการที่ Vue.js เปรียบเทียบ DOM ปัจจุบันกับ Virtual DOM ใหม่
ที่ถูกสร้างขึ้นจากการเปลี่ยนแปลงของข้อมูลหรือสถานะ เมื่อพบความแตกต่าง Vue.js จะทำการ
อัพเดตเฉพาะส่วนที่เปลี่ยนแปลงใน DOM จริง วิธีนี้เป็นการปรับปรุงประสิทธิภาพเนื่องจากไม่จำเป็น
ต้องสร้าง DOM ใหม่ทั้งหมด
 

ข้อดีของการแพทช์:

1.ประสิทธิภาพ: การแพทช์ทำให้ DOM อัพเดตเร็วขึ้นเพราะเปลี่ยนเฉพาะส่วนที่จำเป็น
2.การจัดการสถานะ: องค์ประกอบ (elements) ที่ไม่ได้เปลี่ยนแปลงจะยังคงสถานะเดิม เช่น 
focus, selection และข้อมูลที่ไม่ถูกเปลี่ยน
 

ข้อเสียของการแพทช์:

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

 

Replacing (การแทนที่)

Replacing คือการแทนที่องค์ประกอบ DOM เดิมทั้งหมดด้วยองค์ประกอบใหม่ ซึ่งหมายความว่า 
Vue.js จะสร้างองค์ประกอบใหม่แทนองค์ประกอบเดิมทุกครั้งที่มีการเปลี่ยนแปลง
 

ข้อเสียของการแทนที่: 

1.ประสิทธิภาพต่ำ: การแทนที่ทั้งหมดจะช้ากว่าการแพทช์เพราะต้องสร้างองค์ประกอบใหม่ทุกครั้ง
2.การสูญเสียสถานะ: การแทนที่ทั้งหมดจะทำให้สูญเสียสถานะภายในองค์ประกอบ เช่น focus, 
selection หรือข้อมูลที่ถูกเก็บในองค์ประกอบนั้น
 

ข้อดีของการแทนที่: 

1.การทำงานที่ง่ายและตรงไปตรงมา: การแทนที่องค์ประกอบทั้งหมดอาจทำให้การทำงานง่ายขึ้น
ในบางกรณี เพราะไม่ต้องสนใจการคำนวณความแตกต่างระหว่าง Virtual DOM และ DOM จริง
ซึ่งเหมาะสมในกรณีที่องค์ประกอบซับซ้อนน้อยหรือเปลี่ยนแปลงบ่อย ๆ และไม่ต้องกังวลเรื่อง
ประสิทธิภาพมากนัก
2.ลดข้อผิดพลาดที่ซับซ้อน: ในบางสถานการณ์ การแทนที่องค์ประกอบทั้งหมดอาจลดปัญหาหรือ
บั๊กที่เกิดจากการคำนวณและการแพทช์ที่ผิดพลาดหรือไม่สมบูรณ์
3.เหมาะสมสำหรับสถานะที่ไม่คงที่: หากองค์ประกอบมีสถานะที่ไม่คงที่ (เช่น แอนิเมชันที่เปลี่ยนแปล
งตลอดเวลา) การแทนที่อาจเป็นทางเลือกที่ง่ายกว่าเพราะไม่ต้องกังวลเรื่องการแพทช์สถานะ
 
โดยทั่วไปแล้วเมื่อมีการอัพเดทลิสรายการของ element ที่ใช้งานด้วย v-for ค่าเริ่มต้น vuejs
จะใช้วิธีการ Patching ดูตัวอย่างประกอบ
 
<script setup>
import { ref, reactive } from 'vue'

const todos = ref(
  [
    { id: 1, name: 'Buy groceries', isComplete: false },
    { id: 2, name: 'Read a book', isComplete: true },
    { id: 3, name: 'Write a blog post', isComplete: false }
  ]
)
// จำลองการเปลี่ยนแปลงค่าใน 10 วินาที
setTimeout(()=>{
  todos.value.reverse()
},10000) 

</script>
<template>
  <ul>
    <li  v-for="todo in todos" >
      <input type="text" > {{ todo.name }}  
    </li>
  </ul>
</template>
 
เราจำลองวนลูปให้แสดงรายการ 3 รายการ และกำหนดให้เปลี่ยนแปลงค่าใน 10 วินาที
โดยก่อนที่ค่าจะเปลี่ยนแปลงโดยการ reverse() หรือค่าก่อนหลัง ให้เราพิมพ์ อะไรก็ได้
ในช่อง แรก หรือช่องที่ 3 ดูรูปผลลัพธ์ประกอบ
 
 

 
 
เมื่อเริ่มต้นโหลดครั้งแรก รายการแสดงปกติ
 
 

 
 
เราพิมพ์คำว่า hello ไว้ในช่องที่ 3 ที่อยู่ใน li ตัวที่ 3 ก่อนข้อมูลจะเปลียนแปลงใน 10 วินาที
 
 

 
 
เมื่อข้อมูลเปลี่ยนแปลง จะเห็นปัญหาที่เกิดขึ้น ว่า input ที่เราพิมพ์ ไม่ได้สลับไปด้วย ทั้งนี้ก็เพราะ
เป็นการทำงานของ vuejs ที่เลือกวิธีการ Patching (การแพทช์) เป็นค่าเริ่มต้น เพื่อให้การจัด
การข้อมูลมีประสิทธิภาพ แต่สำหรับกรณีนี้ การ Patching ไม่ใช้วิธีที่เหมาะในการใช้งาน ตาม
ที่อธิบายข้อดีและข้อเสียด้านบน และเพื่อให้การจัดการเป็นไปอย่างถูกต้อง เราจึงควรกำหนด key
ซึ่งเป็น attribute พิเสษ ที่ใช้งานร่วมกับ v-bind เขียนแบบย่อเป็น :key โดยจะกำหนดค่าได้
เป็นตัวเลขหรือข้อความก็ได้ และเป็นค่าที่ซ้ำกัน  ไม่สามารถกำหนดค่าเป็น object ได้
เรามาลองดูโค้ดที่เพิ่มการใช้งาน key เข้าไป เป็นดังนี้
 
<script setup>
import { ref, reactive } from 'vue'

const todos = ref(
  [
    { id: 1, name: 'Buy groceries', isComplete: false },
    { id: 2, name: 'Read a book', isComplete: true },
    { id: 3, name: 'Write a blog post', isComplete: false }
  ]
)
// จำลองการเปลี่ยนแปลงค่าใน 10 วินาที
setTimeout(()=>{
  todos.value.reverse()
},10000) 

</script>
<template>
  <ul>
    <li  v-for="todo in todos" :key="todo.id">
      <input type="text" > {{ todo.name }}  
    </li>
  </ul>
</template>
 
ในที่นี้เราอาศัยค่าจาก todo.id ซึ่งเป็นค่าที่ไม่ซ้ำของแต่ละรายการมาใช้งาน 
 
 

 
 
เมื่อเริ่มต้นโหลดครั้งแรก รายการแสดงปกติ
 
 

 
 
เราพิมพ์คำว่า hello ไว้ในช่องที่ 3 ที่อยู่ใน li ตัวที่ 3 ก่อนข้อมูลจะเปลียนแปลงใน 10 วินาที
 
 

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

 
 

การตรวจจับการเปลี่ยนแปลงของข้อมูล Array

อย่างที่เราได้ดูตัวอย่างข้างต้น ข้อมูลที่ใช้สำหรับวนลูปหลักๆ จะเป็นข้อมูล array ดังนั้นการเปลี่ยน
แปลงที่เกิดกับ array ย่อมมีผลต่อรูปแบบการแสดงหรือการเรนเดอร์ลิสรายการ ใน vuejs สามารถ
ตรวจจับการเปลี่ยนแปลงของข้อมูล array เมื่อมีการใช้งานฟังก์ชั่นต่อไปนี้
 
push() pop() shift() unshift() splice() sort() และ reverse()
 
แต่ละเมธอดของอาร์เรย์ใน JavaScript มีหน้าที่และการใช้งานต่าง ๆ ดังนี้:
 

1. push()

คำอธิบาย: เพิ่มสมาชิกหนึ่งตัวหรือมากกว่าลงในตำแหน่งสุดท้ายของอาร์เรย์ และ
คืนค่าความยาวของอาร์เรย์ใหม่
รูปแบบ: array.push(สมาชิก1, ..., สมาชิกN)
ตัวอย่าง:
let arr = [1, 2, 3];
arr.push(4);
console.log(arr); // Output: [1, 2, 3, 4]
 

2. pop()

คำอธิบาย: นำสมาชิกตัวสุดท้ายออกจากอาร์เรย์ และคืนค่าสมาชิกนั้น ๆ ออกมา การใช้เมธอดนี้จะเปลี่ยนความยาวของอาร์เรย์
รูปแบบ: array.pop()
ตัวอย่าง:
let arr = [1, 2, 3, 4];
let lastElement = arr.pop();
console.log(arr); // Output: [1, 2, 3]
console.log(lastElement); // Output: 4
 

3. shift()

คำอธิบาย: นำสมาชิกตัวแรกออกจากอาร์เรย์ และคืนค่าสมาชิกนั้น ๆ ออกมา 
การใช้เมธอดนี้จะเปลี่ยนความยาวของอาร์เรย์
รูปแบบ: array.shift()
ตัวอย่าง:
let arr = [1, 2, 3, 4];
let firstElement = arr.shift();
console.log(arr); // Output: [2, 3, 4]
console.log(firstElement); // Output: 1
 

4. unshift()

คำอธิบาย: เพิ่มสมาชิกหนึ่งตัวหรือมากกว่าลงในตำแหน่งแรกของอาร์เรย์ และ
คืนค่าความยาวของอาร์เรย์ใหม่
รูปแบบ: array.unshift(สมาชิก1, ..., สมาชิกN)
ตัวอย่าง:
let arr = [2, 3, 4];
arr.unshift(1);
console.log(arr); // Output: [1, 2, 3, 4]
 

5. splice()

คำอธิบาย: เปลี่ยนเนื้อหาของอาร์เรย์โดยการลบหรือแทนที่สมาชิกที่มีอยู่แล้วและ/หรือเพิ่ม
สมาชิกใหม่ลงในตำแหน่งนั้น ๆ ตามที่กำหนด
รูปแบบ: array.splice(ตำแหน่งเริ่มต้น, จำนวนที่จะลบ, สมาชิก1, สมาชิก2, ...)
ตำแหน่งเริ่มต้น: ตำแหน่งที่จะเริ่มเปลี่ยนแปลงอาร์เรย์
จำนวนที่จะลบ: จำนวนสมาชิกที่ต้องการลบ
สมาชิก1, สมาชิก2, ...: สมาชิกที่ต้องการเพิ่มเข้าไปในอาร์เรย์ โดยเริ่มต้นที่ตำแหน่งที่ระบุ
ตัวอย่าง:
let arr = [1, 2, 3, 4];
arr.splice(1, 2, 'a', 'b'); // ลบ 2 สมาชิกตั้งแต่ตำแหน่งที่ 1 แล้วเพิ่ม 'a' และ 'b' เข้าไป
console.log(arr); // Output: [1, 'a', 'b', 4]
 

6. sort()

คำอธิบาย: เรียงลำดับสมาชิกของอาร์เรย์ตามลำดับที่กำหนด โดยลำดับเริ่มต้นคือการแปลง
สมาชิกให้อยู่ในรูปของสตริงและเปรียบเทียบค่าของรหัสหน่วย UTF-16
รูปแบบ: array.sort([ฟังก์ชันเปรียบเทียบ])
ฟังก์ชันเปรียบเทียบ: ตัวเลือกทางเลือก เป็นฟังก์ชันที่ใช้เพื่อกำหนดลำดับการเรียงของสมาชิก 
ถ้าไม่ระบุฟังก์ชัน เมธอดจะเรียงสมาชิกตามตัวอักษร Unicode ในลำดับน้อยไปหามาก
ตัวอย่าง:
let arr = [3, 1, 4, 2];
arr.sort(); // เรียงลำดับตามค่าเริ่มต้น
console.log(arr); // Output: [1, 2, 3, 4]

let arr2 = [3, 1, 4, 2];
arr2.sort((a, b) => b - a); // เรียงลำดับจากมากไปหาน้อย
console.log(arr2); // Output: [4, 3, 2, 1]
 

7. reverse()

คำอธิบาย: ย้อนกลับลำดับของสมาชิกในอาร์เรย์ โดยเปลี่ยนแปลงตัวอาร์เรย์เดิมและคืนค่า
อาร์เรย์ที่ถูกย้อนกลับ
รูปแบบ: array.reverse()
ตัวอย่าง:
let arr = [1, 2, 3, 4];
arr.reverse();
console.log(arr); // Output: [4, 3, 2, 1]
 
ฟังก์ชั่นดังกล่าวข้างต้นจะมีผลกับตัวแปร array ที่ใช้งานนั่นคือค่าของ array นั้นๆ มีการ
เปลี่ยนแปลงไปตามรูปแบบฟังก์ชั่นหรือคำสั่งที่ใช้งาน แต่ก็ยังมี คำสั่ง ที่ไม่มีการเปลี่ยนแปลง
ค่า array เริ่มต้น แต่เป็นการแทนที่ด้วยค่า array ใหม่ที่ได้จากการเปลี่ยนแปลงค่าแล้ว
โดยไม่แตะต้องตัว array เพิ่ม เช่นคำสั่ง filter(), concat() และ slice() เป็นตัน
 

1. filter()

คำอธิบาย: ใช้สร้างอาร์เรย์ใหม่ที่ประกอบด้วยสมาชิกที่ผ่านเงื่อนไขที่กำหนดไว้ในฟังก์ชันของ filter
รูปแบบ: array.filter(callback(element[, index[, array]])[, thisArg])
callback: ฟังก์ชันที่ใช้ในการตรวจสอบเงื่อนไข ฟังก์ชันนี้ต้องคืนค่าเป็น true เพื่อให้สมาชิกนั้น ๆ 
ถูกเก็บไว้ในอาร์เรย์ผลลัพธ์
thisArg (ตัวเลือก): วัตถุที่ถูกใช้เป็นค่า this ในการเรียกฟังก์ชัน callback
ตัวอย่าง:
let numbers = [1, 2, 3, 4, 5, 6];
let evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // Output: [2, 4, 6]
 

2. concat()

คำอธิบาย: ใช้เชื่อมต่อ (concatenate) อาร์เรย์ทั้งหมดที่ระบุเข้าด้วยกันเพื่อสร้างอาร์เรย์ใหม่
รูปแบบ: array.concat(value1[, value2[, ...[, valueN]]])
value1, value2, ..., valueN: ค่าหรืออาร์เรย์ที่ต้องการเชื่อมต่อเข้าด้วยกัน
ตัวอย่าง:
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let concatenatedArray = arr1.concat(arr2);
console.log(concatenatedArray); // Output: [1, 2, 3, 4, 5, 6]
 

3. slice()

คำอธิบาย: สร้างสำเนาของอาร์เรย์โดยเลือกสมาชิกของอาร์เรย์ตามช่วงที่กำหนด
รูปแบบ: array.slice([begin[, end]])
begin (ตัวเลือก): ตำแหน่งเริ่มต้นที่จะเลือก ค่าเริ่มต้นคือ 0 (อาร์เรย์ตั้งแต่สมาชิกแรก)
end (ตัวเลือก): ตำแหน่งสุดท้าย (ไม่รวม) ที่จะเลือก ค่าเริ่มต้นคือความยาวของอาร์เรย์
ตัวอย่าง:
let fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
let citrus = fruits.slice(1, 3);
console.log(citrus); // Output: ['Orange', 'Lemon']
 
เมธอดเหล่านี้เป็นเครื่องมือที่มีประโยชน์ในการจัดการข้อมูลในอาร์เรย์ใน JavaScript โดย
มีความสามารถที่หลากหลาย เช่น เพิ่ม ลบ และเรียงลำดับข้อมูล ซึ่งช่วยให้การจัดการข้อมูลเป็น
ไปอย่างมีประสิทธิภาพและง่ายต่อการใช้งานได้
 
เนื้อหาเกี่ยวกับการใช้งาน v-for เบื้องต้น และความรู้เกี่ยวกับการจัดการ array  ก็ขอจบเพียง
เท่านี้ ตอนหน้าจะเป็นอะไร รอติดตาม





กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ



อ่านต่อที่บทความ



ทบทวนบทความที่แล้ว









เนื้อหาที่เกี่ยวข้อง






เนื้อหาพิเศษ เฉพาะสำหรับสมาชิก

กรุณาล็อกอิน เพื่ออ่านเนื้อหาบทความ

ยังไม่เป็นสมาชิก

สมาชิกล็อกอิน



( หรือ เข้าใช้งานผ่าน Social Login )




URL สำหรับอ้างอิง





คำแนะนำ และการใช้งาน

สมาชิก กรุณา ล็อกอินเข้าระบบ เพื่อตั้งคำถามใหม่ หรือ ตอบคำถาม สมาชิกใหม่ สมัครสมาชิกได้ที่ สมัครสมาชิก


  • ถาม-ตอบ กรุณา ล็อกอินเข้าระบบ
  • เปลี่ยน


    ( หรือ เข้าใช้งานผ่าน Social Login )







เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ