Subscribe on changes!

Child component attribute updates break when using a transition component inside a teleport component

avatar
Jul 20th 2021

Version

3.1.5

Reproduction link

SFC Playground Reproduction

Steps to reproduce

  1. Toggle the Enable Class checkbox to turn the class on and off. Note the child component content background is not turning red.
  2. Untick the Transition? checkbox.
  3. Repeat step 1 and note the child component content background is turning red.

What is expected?

The child component should have the .some-class class applied to it when used inside a transition in a teleport component.

What is actually happening?

The class is not being applied


This was working in v3.1.3 however I can't select v3.1.3 to reproduce a working version in the SFC playground as there appears to be an API change between v3.1.3 and v3.1.5 which breaks the demo.

avatar
Jul 20th 2021

This may be related to #4155

avatar
Jul 21st 2021

attrs is not reactive but it should be usable in the template. I think this is a bug but I'm not completely sure

avatar
Jul 21st 2021

without teleport also has same problem, see playground

avatar
Jul 21st 2021

This is a bug specific to useAttrs. For now you can simply bind to $attrs directly in the template.

It's also not teleport or transition related. Any component that renders default slot can lead to this behavior.

avatar
Jul 21st 2021

@yyx990803 Thanks for sorting those out so quickly! That's great!

I have a few lingering questions regarding this though.

To give you a bit of context, the reason this has become an issue for me is because I have a composition that splits the attrs object in a higher-order component with inheritAttrs: false so that specific subsets of attributes can be redirected to different child components (ie. onBeforeEnter to a Transition and class to a div or something like that). Here's an SFC playground example of what I am trying to achieve.

Previously this worked by using a customRef. After the latest fix I can achieve the same result using an object with getters that point back to the original attrs object and a __vInternal: 1 flag to notify Vue to update. Here's a working SFC playground example

As far as I am aware it is quite a common use-case to redirect subsets of attributes from higher-order components to different parts of the template. In light of this, I am curious as to the following:

  1. Is my approach to splitting the attrs object completely nuts and, if so, is there a better alternative that doesn't rely on using internal flags like __vInternal: 1?
  2. In your experience is this a common use-case among other devs working on medium-large Vue codebases?
  3. If 2 is true, would it be reasonable to request an official splitAttrs API shipped with Vue to perform these operations?

Thanks again for looking into this.