簡體   English   中英

Vue js / javascript對象數組-如何檢測是否有任何對象已更改以及哪個對象已更改

[英]Vue js / javascript array of objects - how to detect if any of the objects has been changed and which one

我正在研究Vuejs項目。 在某種程度上,我有一個對象數組(從服務器獲取的數據),如下所示:

[
    {
        name: "Book one",
        price: 12,
        active: true
    },
    {
        name: "Small drone X12",
        price: 54,
        active: false
    },
    {
        name: "something else",
        price: 32,
        active: true
    }
]

數據用於在頁面上生成動態表單,因此用戶可以編輯數據。 如何檢查用戶是否更改了任何對象,以及哪些對象(可以更改為一個,兩個或任意數量的對象),因此可以向用戶顯示一個按鈕來更新更改的數據。 我只想更新實際上已更改的對象中的數據-並非全部。

您可以在映射數組中保留對象的已計算JSON字符串

const comparison = data.map(JSON.stringify); // in order string based values for direct comparison

稍后在代碼中,您可以與這些值進行比較

data.forEach((obj, index) => {
  // if they do match, skip
  if (JSON.stringify(obj) === comparison[index]) return;

  // they don't match, update comparison value
  comparison[index] = JSON.stringify(obj);

  // update VUE state and other things here
})

這樣,您只需要更新更新的值,並且只需要計算比較值即可。 即使對象已更新某些字段但仍是同一對象(即使值已更新,也將通過object === object的相等性測試),該方法仍然有效。

另一個涉及更多的示例圍繞代理或觀看對象上的每個設置器以在每次對其進行適當更新時觸發更改,但是對於我來說,我仍然不正確地理解代理...

如果字段數組更改大小該怎么辦?

如果數據永遠不會改變,這會起作用,但是如果數據數組的大小會改變,它仍然會起作用,因為匹配索引中將存在未定義的值,從而導致字符串比較返回false。 但是最好將其添加到表單中,然后最后對上述代碼進行簡單的修改:

if (comparison[index] === undefined) {
  // add the form to the field, it'll add in order
}
// they don't match, update comparison value
...

一種方法是在傳遞對象的數組索引和已修改字段的屬性名稱時偵聽change事件。 然后將該值分配給另一個保存更改的數組。

 new Vue({ el: '#app', data: () => ({ items: [ { name: "Book one", price: 12, active: true }, { name: "Small drone X12", price: 54, active: false }, { name: "something else", price: 32, active: true } ], changed: [] }), mounted () { this.changed = Array(this.items.length).fill({}) }, methods: { onPropertyChanged (index, prop) { this.changed.splice(index, 1, Object.assign({}, this.changed[index], { [prop]: this.items[index][prop] })) } } }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <div v-for="(item, index) in items" :key="index"> <label>Name</label> <input v-model="item.name" @change="onPropertyChanged(index, 'name')"> <label>Price</label> <input v-model="item.price" type="number" min="0" @change="onPropertyChanged(index, 'price')"> <label>Active</label> <input v-model="item.active" type="checkbox" @change="onPropertyChanged(index, 'active')"> </div> <hr/> <h4>Changes</h4> <pre v-for="(item, index) in changed" :key="`change-${index}`"><code>{{ item }}</code></pre> </div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM