When attempting to utilize components within a v-for
loop and initialize the ref
for future access to their methods from the parent component, I encountered an issue. Below is a simplified version of the code that demonstrates my scenario:
<template>
<div class="hello">
{{ msg }}
<ul>
<list-item
v-for="item in items"
:key="item.id"
:value="item.text"
:ref="`item${item.id}`"
/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
name: "HelloWorld",
components: {
ListItem
},
data() {
return {
msg: "Welcome to Your Vue.js App",
items: [
{ id: 1, text: "foo" },
{ id: 2, text: "bar" },
{ id: 3, text: "baz" },
{ id: 4, text: "foobar" }
]
};
},
mounted() {
setTimeout(() => this.$refs.item2.highlight(), 1500);
}
};
</script>
The ListItem
component looks like this:
<template>
<li v-bind:class="{ highlight: isHighlighted }">
{{value}}
</li>
</template>
<script>
export default {
name: "list-item",
props: ["value"],
data() {
return {
isHighlighted: false
};
},
methods: {
highlight() {
this.isHighlighted = !this.isHighlighted;
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.highlight {
color: red;
}
</style>
The initial attempt resulted in an error stating:
Uncaught TypeError: _this.$refs.item2.highlight is not a function
. After further investigation, I discovered that refs defined within a v-for
loop are not direct components but arrays containing the single component.What is the rationale behind this behavior? How does it relate to the 'f' wrapper? Has anyone else encountered this issue and can provide an explanation or solution?
Although using
setTimeout(() => this.$refs.item2[0].highlight(), 1500);
worked, must one always pass [0]
? Is there a more efficient approach available? Any assistance would be greatly appreciated.