Here's an interesting example to ponder:
<template>
<div>
<button @click="addItem">Add Item</button>
<h1>Fruits</h1>
<ul>
<li
v-for="(item, index) in items"
ref="items"
v-bind:key="item.id"
@click="logIndex(index)"
>
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
name: "Fruits",
data() {
return {
items: [
{ name: "apple", id: 1 },
{ name: "banana", id: 2 },
],
};
},
methods: {
addItem() {
const nextNumber = Math.max(...this.items.map((x) => x.id)) + 1;
this.items.unshift({
name: "peach " + nextNumber,
id: nextNumber,
});
console.log(this.$refs);
console.log(this.items);
},
logIndex(index) {
console.log(index);
console.log(this.items[index]);
console.log(this.$refs.items[index]); //this seems reasonable to assume
//using the index here would return
//the correct reference, but maybe not
},
},
};
</script>
Upon inspecting the console logs, it becomes evident that the order of refs and items is not consistent. Clicking on a fruit item will log that specific item, revealing the discrepancy. What could be causing this inconsistency? Do refs have a distinct order for a specific reason?
Explore this example further on CodeSandbox View demonstration
Unpacking the Issue:
Encountering this dilemma raised a critical question. Picture a scenario where a component comprises an array of child components. If the need arises to interact with a sibling component, emitting from the initiating component and handling the event on the parent component is a common practice. However, leveraging the index for direct access fails when the initial array undergoes modification. An alternative approach utilizing .find and matching on component data proved to be effective.
While adopting Vuex or a similar methodology may offer a more robust solution in the mentioned situation, an investigation into the discrepancy between this.$refs and the underlying data's sort order remains intriguing. Your insights on why this disparity exists and any workaround suggestions would be greatly appreciated.