เมื่อไม่กี่วันก่อนได้มีโอกาศทำโปรเจคนึงแล้วจะต้องนำ array มา render ด้วย v-for โดยจะมีฟังก์ชั่นนึงเพื่อเข้าไปเปลี่ยนค่าใน array ตามตัวอย่างนี้

data () {
  return {
    items: ['a', 'b', 'c']
  }
}

this.items[1] = 'x' // is NOT reactive

ปรากฏว่าตัว v-for ที่ render this.items มันดันไม่ render ค่าใหม่มันยังเป็น a, b, c เหมือนเดิมทั้งๆที่ควรจะเป็น a, x, c ก็เลยไปเจอสาเหตุมาจาก document ของ vuejs ตามลิงก์นี้

Due to limitations in JavaScript, Vue cannot detect the following changes to an array

จากข้อจำกัดของ javascript ทำให้ vue ไม่สามารถตรวจจับได้ว่า array เปลี่ยนแปลง

เพื่อแก้ปัญหานี้เราสามารถแก้ได้ 2 วิธีคือ

this.$set(this.items, indexOfItem, newValue)
// this.$set(this.items, 1, 'x')
this.items.splice(indexOfItem, 1, newValue)
// this.items.splice(1, 1, 'x')

เท่านี้ตัว v-for ของเราก็ re-rendered ใหม่อย่างสวยงาม

แต่ในเคสของผมจะเป็น object in array โดยหน้าตา array จะประมานนี้

[
	{
		"id": 190,
		"status": "ok",
		"remark": null
	}
]

เมื่อคลิก button ซักอันเพื่อเปลี่ยน status ก็จะอัพเดทด้วยท่านี้

this.vendorItems.splice(index, 1, Object.assign(this.vendor.items[index], {
	status: 'cancel',
        remark: 'test'
}))

เกี่ยวกับผู้เขียน

Itthipat Thitsarak

สวัสดีครับผม อิทธิพัทธ์ (เป้) เป็น Freelance Web developer ชอบหาเทคนิคต่างๆที่ทำให้ชีวิต Programmer ง่ายขึ้นโดย Blog นี้จะ สอน Laravel, Vuejs, CSS, HTML 5 และอื่นๆ ที่เกี่ยวกับการทำเว็บไซต์

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

Scroll to Top
Scroll to Top