เมื่อไม่กี่วันก่อนได้มีโอกาศทำโปรเจคนึงแล้วจะต้องนำ 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'
}))