Vue: this.$refs doesn't get updated upon element / component removal

Created on 27 Dec 2016  路  3Comments  路  Source: vuejs/vue

If you have a dynamic array that you iterated through and displayed elements or components for; If you were to make the array smaller by means of removing an array element fair enough it will update the DOM but it will not update this.$refs.

One may point out that adding refs to something that is dynamic is a stupid idea. I was using this because I have a dynamic amount of tabs, and each tab has it's own unique key. In some cases, I may need to trigger an "action" on a specific tab view. I could have used an event bus but I feel as if using refs was a suitable solution to this.

I expect that when you remove an element that was referenced, this.$refs would be updated as the referenced element or component no longer exists. This isn't the case.

I have provided a fiddle: https://jsfiddle.net/ny5h4jgn/

You will be presented with a view containing the array of elements and the list of references (I tried doing {{ Object.keys(this.$refs) }} but it wasn't quite so reliable. There is a button to remove the last element on the array and upon doing so, the ref list does not update.

I can confirm that upon adding an element that uses the same ref name was what was removed, does work as expected with no issues regarding the ref already existing. So it doesn't seem to be a major problem but depending on what you are doing with this.$refs it could be a problem.

Most helpful comment

FYI, when ref is used on or inside v-for, they are registered as Arrays. In your case, each property on $refs is an Array:

$refs: {
  one: [{...}],
  two: [{...}],
  three: [{...}]
}

This is because typically you'd use the same ref id for all items and they will be collected in the same array.

When you pop an item, the three Array actually becomes empty.

In the future we may support passing a function to the ref binding so that the user can customize how to register refs, e.g:

<div v-for="com in coms" :ref="ref => { $refs[com] = ref }">

All 3 comments

@JTallis $refs is not reactive, you could take a look at https://vuejs.org/v2/api/#ref

FYI, when ref is used on or inside v-for, they are registered as Arrays. In your case, each property on $refs is an Array:

$refs: {
  one: [{...}],
  two: [{...}],
  three: [{...}]
}

This is because typically you'd use the same ref id for all items and they will be collected in the same array.

When you pop an item, the three Array actually becomes empty.

In the future we may support passing a function to the ref binding so that the user can customize how to register refs, e.g:

<div v-for="com in coms" :ref="ref => { $refs[com] = ref }">

When adding or removing a element in a array that is used in a v-for, how do i keep track of refs array, the index is always one behind when adding a new element.

Was this page helpful?
0 / 5 - 0 ratings