Skip to content

fix(TransitionGroup): should render the VNode that is actually keyed #3568

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

Closed
wants to merge 1 commit into from
Closed

fix(TransitionGroup): should render the VNode that is actually keyed #3568

wants to merge 1 commit into from

Conversation

HcySunYang
Copy link
Member

@HcySunYang HcySunYang commented Apr 8, 2021

Fix: #3552

In the current implementation, the TransitionGroup component will extract the raw vnodes(getTransitionRawChildren) as the content it will render. This is problematic in some scenarios, e.g.

<TransitionGroup tag="ul">
  <template v-for="a in b" key="a">
    <li v-if="c">xxx</li>
  </template>
</TransitionGroup>

The above template will be compiled as:

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock(_TransitionGroup, { tag: "ul" }, {
    default: _withCtx(() => [
      (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.b, (a) => {
        return (_openBlock(), _createBlock(_Fragment, { key: "a" }, [
          (_ctx.c)
            ? (_openBlock(), _createBlock("li", { key: 0 }, "xxx"))
            : _createCommentVNode("v-if", true)
        ], 64 /* STABLE_FRAGMENT */))
      }), 128 /* KEYED_FRAGMENT */))
    ]),
    _: 1 /* STABLE */
  }))
}

This means that the actual content rendered by the TransitionGroup component is:

const TransitionGoupp = {
  render() {
    return createVNode(tag, null, [
      h("li", { key: 0 }, "xxx"),
      h("li", { key: 0 }, "xxx"),
      h("li", { key: 0 }, "xxx"),
      h("li", { key: 0 }, "xxx"),
      ......
    ])
  }
}

The behavior of the TransitionGroup component to extract the raw VNodes breaks the hierarchical structure of the virtual DOM tree, leading to subsequent rendering issues, but this is necessary to set the transition hook.

My idea is to still extract raw vnodes in order to set the transition hook, but when rendering, we need to render the node that is actually keyed, this means we need to support transition when removing Fragment.

@HcySunYang HcySunYang added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope: transition labels Apr 8, 2021
@yyx990803 yyx990803 added 🔩 p2-edge-case and removed 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Jul 15, 2021
@yyx990803 yyx990803 deleted the branch vuejs:master January 18, 2022 08:31
@yyx990803 yyx990803 closed this Jan 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

v-if works incorrectly when using with sparse array
2 participants