Reputation: 20309
I have seen multiple examples where indexOf
is used within Vue to select an object from an array of objects like this:
Script:
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!',
items: [
{
id: 1,
name: 'test'
},
{
id: 2,
name: 'hello'
},
{
id: 3,
name: 'world'
}
]
},
methods: {
deleteItem(item) {
console.log(this.items.indexOf(item));
// splice the item.
}
}
})
Template:
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p>{{ message }}</p>
<ul>
<li v-for="item in items" @click=deleteItem(item)>
{{ item.name }}
</li>
</ul>
</div>
https://jsfiddle.net/5gwtyv3h/
Now I am wondering this is even possible. If I go into my console and simply do this:
const items = [
{
id: 1,
name: 'test'
},
{
id: 2,
name: 'hello'
},
{
id: 3,
name: 'world'
}
];
items.indexOf({ id: 1, name: 'test'});
I get -1 because the item can not be found. Is Vue doing something that makes this possible or I missing something else here?
Upvotes: 1
Views: 496
Reputation: 26878
You will have to cache the object that you add to the Array or do a deep find()
or findIndex()
comparison.
For Objects compared with indexOf
, they have to be the exact same Object, meaning, they must refer to the exact same Object instance.
const a = {
foo: "bar"
},
b = {
foo: "bar"
};
console.log(a === b); // false
Consider this:
const a = {
foo: "bar"
},
b = {
foo: "bar"
};
const c = [a, b];
console.log(c.indexOf({
foo: "bar"
})); // -1 since the Object you **just** made won't be in the array
console.log(c.indexOf(a)); // 0 you're looking for the right object by reference
console.log(c.findIndex(i => i.foo === "bar")); // 0 again since it does a deep compare
// Succinct deep compare using lodash
console.log(_.findIndex(c, i => _.isEqual(i, {
foo: "bar"
}))); // 0 again but deep compare logic is encapsulated
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
Upvotes: 3