Reputation: 590
Is it possible to access an element within the nested v-for loop by using the refs index of the element? I mean, I'm trying to focus a textbox that is within the nested v-for loop which I used to access by its refs index. It works fine for a single v-for loop but not with nested.
For more details here's my loop structure:
This works
<div v-for="(comItem, index) in commentItems" :key="comItem.commentId">
<textarea ref="addRep" ></textarea>
</div>
this.$nextTick(() => {
this.$refs.addRep[index].focus()
});
This won't work
<div v-for="(cont, i) in contentItems" :key="cont.contentId">
...
<div v-for="(comItem, index) in commentItems" :key="comItem.commentId">
<textarea ref="addRep" ></textarea>
</div>
</div>
this.$nextTick(() => {
this.$refs.addRep[index].focus()
});
Or
this.$nextTick(() => {
this.$refs.addRep[i].focus()
});
With the nested html v-for loop structure. The focus will just jump around anywhere. To anyone who encountered this kind of scenario. Please assist me if you know the solutions. Thanks.
Upvotes: 2
Views: 2855
Reputation: 29102
Trying to calculate the appropriate index within addRep
is a little tricky. You'd need the values of both i
and index
and then count up through the relevant arrays to work out the appropriate index.
A simpler way to do this is to use a dynamic ref
name. We still need i
and index
to find the relevant element but there's no calculation required.
The core trick here is to set the ref to :ref="`addRep${i}`"
, or equivalently :ref="'addRep' + i"
if you prefer. So you'll end up with multiple named refs, addRep0
, addRep1
, etc., each with its own array of elements. The value of i
tells you the ref name and the index
tells you the index within that array.
Here's an example:
new Vue({
el: '#app',
data () {
return {
contentItems: [
{
contentId: 1,
comments: [
{
commentId: 1,
text: 'A'
}, {
commentId: 2,
text: 'B'
}, {
commentId: 3,
text: 'C'
}
]
}, {
contentId: 2,
comments: [
{
commentId: 1,
text: 'D'
}
]
}, {
contentId: 3,
comments: [
{
commentId: 1,
text: 'E'
}, {
commentId: 2,
text: 'F'
}
]
}
]
}
},
methods: {
onButtonClick (i, index) {
this.$refs[`addRep${i}`][index].focus()
}
}
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<div v-for="(cont, i) in contentItems" :key="cont.contentId">
<h4>{{ cont.contentId }}</h4>
<div v-for="(comItem, index) in cont.comments" :key="comItem.commentId">
<textarea :ref="`addRep${i}`" v-model="comItem.text"></textarea>
<button @click="onButtonClick(i, index)">Focus</button>
</div>
</div>
</div>
Upvotes: 4