Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refs inside v-for leaking to slots #10851

Open
yuwu9145 opened this issue May 2, 2024 · 3 comments
Open

Refs inside v-for leaking to slots #10851

yuwu9145 opened this issue May 2, 2024 · 3 comments

Comments

@yuwu9145
Copy link
Contributor

yuwu9145 commented May 2, 2024

Vue version

3.4.25

Link to minimal reproduction

https://play.vuejs.org/#eNqNk8Fu2zAMhl+F0CUp4Dlos10MN8AW9LAd1qHbbRoGLaYTdbIkSLKXwfC7l5LjpCmCoidL4s9fFPm5Zx+tzbsWWcFKv3HShhXXsrHGBVjvpKqgdqaBWb5IuyidcY37JKiwFq0K0HMNsDGUpVEHX0B/yB2yGKlEEPOrUQXgMLROTzsAJX0o4Od1BjcZLH+Nx0P8xGxalItjYbQJ2FglAtIOoNxdr+4talgb7Y3C7HCvVybQRTVIDwK81FuFgAobKg+Ec+J/uaDUZDFmdO9q4245k+QPUqeqOEsK0kyXkixaFwF9IHEP1hnrqdpJSVpLoj9SVxRPUc5g1feQjIehXNjJdHH+lLHBtD4LsIwFvzG6ltv80RtNc0qd4yz2Wyp09zZIej1n1PbRmTOhlPn3JZ0F12KaQsrZ4ebvhfNHv49nnH1z6NF1yNkxFoTbIvUihu++f8U9rY/BxlStIvUrwQekybSxxlH2qdUVlf1Ml6r9nJijSf3wd/uA2k+PioVONEQ1Ebh+5emncpf5+5RHEFEXj/heIr1PsAwH1kfGL1PuiV57gpkm40Oa7QMZ3Eab+dU55xBhib/EpBpOdAM0ptUBqwLqVm/ia869ielcme18ds71LIOwkz6P1vnBN++EajFd/oYfp5LdxOFuuSqTsRYNErXRlKAtEr2JcrqR5vDsrkQ82VMWfchgJHg0fcnv7w5dnCY1nkaS33xgwxNvNnj/

Steps to reproduce

  1. Open reproduction link
  2. Check console logs

What is expected?

Ref from slot props should have single element assignment

What is actually happening?

Ref from slot props has an array containing a single element

System Info

No response

Any additional comments?

Correct behaviour should be:

  • When assigning the same reactive ref to template ref inside v-for, it should hold an array of refs demo
  • When each v-for element has unique reactive ref assigned, it should return the individual element ref only
@skirtles-code
Copy link
Contributor

I believe this changed in 3.4.24, as a result of #10706.

I can see how the array is undesirable in this example, but on the flip side, the change above does make v-bind and :ref behave the same way. e.g. Playground. The :ref example was already using an array, even prior to 3.4.24, so the new behaviour for v-bind seems more consistent.

The array is needed in the general case, and it isn't clear to me that there's a well-defined special case here where the array could be omitted.

@yuwu9145
Copy link
Contributor Author

yuwu9145 commented May 3, 2024

We have a virtual-scroll component supports dynamic item height, each individual virtual-scroll-item grabs slot dom defined in parent via template ref, so its internal logic can use ResizeObserver to respond to the unpredictable slot dom size.

In this case, each slot element's ref attr has an unique ref assigned from their base components. I would imagine technically Vue should be able to smartly figure out whether each v-for element is assigned an unique ref (e.g. from base comp) or the same ref defined in local parent. The former should return the dom itself while the latter returns an array.

For now, function ref el => itemRef.value = el is used to enforce itemRef to be assigned dom itself, it's a workaround and it's working pretty good. demo

I think the reproduction link in the issue does show some symptom, not sure if it's an official bug but I do feel certain improvement could be made here

@quiteeasy
Copy link
Contributor

We have a virtual-scroll component supports dynamic item height, each individual virtual-scroll-item grabs slot dom defined in parent via template ref, so its internal logic can use ResizeObserver to respond to the unpredictable slot dom size.

In this case, each slot element's ref attr has an unique ref assigned from their base components. I would imagine technically Vue should be able to smartly figure out whether each v-for element is assigned an unique ref (e.g. from base comp) or the same ref defined in local parent. The former should return the dom itself while the latter returns an array.

For now, function ref el => itemRef.value = el is used to enforce itemRef to be assigned dom itself, it's a workaround and it's working pretty good. demo

I think the reproduction link in the issue does show some symptom, not sure if it's an official bug but I do feel certain improvement could be made here

While implementing the suggested behavior is possible, it risks introducing breaking changes. We should carefully evaluate the potential implications and compatibility issues before we go ahead with the implementation. I can implement this change if the team deems it appropriate after the necessary evaluations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants