Subscribe on changes!

v-for ref behaves differently under production and development

avatar
Sep 19th 2022

Vue version

3.2.29

Link to minimal reproduction

https://sfc.vuejs.org/#__DEV__eNp9Uj1v2zAQ/SsHLpYBiXTiqa4cpEOHAu3SteygSmeXLb9AUsog6L/nSMWJkwBZhPt67/HuaWZfvOfTiOzA2tgH5RNETKMH3dnzUbIUJbuTVhnvQoIZAp5qcPaHG23CoYbeGT+WaMIQlbOwwCk4Axsi3Ugrbe9sTKAVfY4ZXv26qeG2hv3v7UtbJTQ/8RQvI2vvWaeqtnC8g1lagMH1o0GbeDcMXycKvhM1WgzVxjtF02FwD3ZTwxUGij6fOj0ij16rHqtdfbP9nJsLaUHe+lsG08y1GtCGNjqNXLtzdXnmylRwCy2z2+0ozjytWI9IJ6OEpr3uElIGMM8X9LLkvB11qVOkFUzNyQW6d54BZct7JcvHeCpmYLEiIzJbuRmsXMQhtCrNVhTeVjyLs5qt9jWm8/xfdJbMLssRc2kQ8eGyrmRkXM4l+5uSjwchRuv/nzk5Le6pJwJZogw2gzP3e37L95/EQK+9rnOMpvkT3EPEQIqS1Vfkgor0szQB7YABw4dib2ZfCb7pvRMt9pAvbHkEVNz6nA==

Steps to reproduce

  1. Click anywhere on the preview 2 times
  2. Change to production and click again 2 times anywhere on the preview

What is expected?

On each click one element is removed from the list. The itemRefs variable should also be updated with the corresponding number of elements

What is actually happening?

Under production everything works as expected, under development the ref array is "lagging" behind. After one click, the list has 2 elements and the ref array still 3. After a second click, the list has 1 element and the ref array has now 2.

System Info

No response

Any additional comments?

Every 2 seconds the itemRefs variable is printed on the console. There you can see that it is actually updated correctly after each click (in both dev and prod scenarios)

avatar
Sep 19th 2022

Sorry, missclicked

avatar
Sep 19th 2022

I don't know... the order is not really the problem here. The source and the ref array are somehow different. The change does also not appear inside a watcher. Like with the clicks, the watcher works fine in production, but in development, it's like if the updated is not sent to the UI and the watcher

Edit: the comment I responded to was deleted

avatar
Sep 21st 2022

I also think this is a bug. When the list changes and the update is triggered, toDisplayString will be called. At this time, the dom has not changed, so the itemRefs value is still 3 divs, and then the converted string is the same as before the update. When comparing dynamicchildren , no updates were made. Also I found that this problem also exists in production mode if the setup syntactic sugar is not used. play

avatar
Sep 21st 2022

With the composition API it does not work either in production or development. See here

avatar
Sep 21st 2022

As a temporary fix, you can create a watcher on the list, then await nextTick(), temporary set the references to [] and finally store the references back into the array. Like this

watch(list.value, async () => {
  await nextTick();
  const temp = itemRefs.value;
  itemRefs.value = [];
  itemRefs.value = temp;
})

Working example

avatar
Oct 3rd 2022

Isn't this a bug? @LinusBorg