Skip to content

fix(Transition): handle KeepAlive + transition leaving edge case #13152

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

Merged
merged 4 commits into from
Aug 20, 2025

Conversation

edison1105
Copy link
Member

@edison1105 edison1105 commented Apr 2, 2025

close #13153

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of v-show transitions for kept-alive components, ensuring the element's display style is correctly set to none when switching components before a transition finishes.
  • Tests

    • Added a new end-to-end test to verify correct behavior when moving a kept-alive node before a v-show transition leave completes.

Copy link

pkg-pr-new bot commented Apr 2, 2025

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@13152

@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@13152

@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@13152

@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@13152

@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@13152

@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@13152

@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@13152

@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@13152

@vue/shared

npm i https://pkg.pr.new/@vue/shared@13152

vue

npm i https://pkg.pr.new/vue@13152

@vue/compat

npm i https://pkg.pr.new/@vue/compat@13152

commit: 37a7201

Copy link

github-actions bot commented Apr 2, 2025

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 101 kB (+24 B) 38.4 kB (+11 B) 34.6 kB (-23 B)
vue.global.prod.js 159 kB (+24 B) 58.6 kB (+10 B) 52.2 kB (-54 B)

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.7 kB (+46 B) 18.3 kB (+22 B) 16.7 kB (+19 B)
createApp 54.6 kB (+46 B) 21.3 kB (+14 B) 19.5 kB (+28 B)
createSSRApp 58.8 kB (+46 B) 23 kB (+28 B) 21 kB (+23 B)
defineCustomElement 59.6 kB (+46 B) 22.8 kB (+28 B) 20.9 kB (+43 B)
overall 68.7 kB (+24 B) 26.4 kB (+11 B) 24.1 kB (+20 B)

@edison1105 edison1105 force-pushed the edison/fix/TransitionLeaving branch from 4673e95 to 5481015 Compare April 3, 2025 01:55
@edison1105 edison1105 added ready to merge The PR is ready to be merged. scope: transition 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Apr 3, 2025
@agileago
Copy link

agileago commented Aug 5, 2025

为啥还不合并发布呢

Copy link

coderabbitai bot commented Aug 5, 2025

Walkthrough

The changes export the leaveCbKey symbol from BaseTransition.ts, update its usage in the renderer to handle early leave cancellation for v-show transitions with KeepAlive, and add an end-to-end test to verify correct display behavior when switching kept-alive components during a transition leave.

Changes

Cohort / File(s) Change Summary
Export leaveCbKey symbol
packages/runtime-core/src/components/BaseTransition.ts
Changed leaveCbKey from a private constant to a public export, making it accessible outside the module.
Renderer transition leave logic
packages/runtime-core/src/renderer.ts
Imported leaveCbKey and added logic in the move function to call the leave callback early if a kept-alive node is moved before a v-show leave transition finishes.
End-to-end test for transition with KeepAlive
packages/vue/__tests__/e2e/Transition.spec.ts
Added a test case verifying that the display style is correctly set to none when switching away from a kept-alive component before a v-show leave transition completes, addressing issue #13153.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant App
    participant KeepAlive
    participant Transition
    participant Renderer

    User->>App: Toggle v-show (start leave transition)
    App->>Transition: Initiate leave
    Transition->>Renderer: Perform leave animation
    User->>App: Switch component before leave finishes
    App->>KeepAlive: Move node
    KeepAlive->>Renderer: move()
    Renderer->>Renderer: Detect _isLeaving, call el[leaveCbKey](true)
    Renderer->>DOM: Set display: none
    Note right of Renderer: Ensures correct display state after switch
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Assessment against linked issues

Objective Addressed Explanation
Fix display state when switching back to kept-alive component after v-show transition leave (#13153)
Add test to verify display is none after switching components before leave finishes (#13153)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes detected.

Suggested reviewers

  • johnsoncodehk

Poem

In the garden where transitions leap,
A rabbit watched components keep.
With v-show and KeepAlive in play,
Now display hides the proper way.
Tests hop in, bugs hop out,
The code is fixed—let’s jump about!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch edison/fix/TransitionLeaving

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/vue/__tests__/e2e/Transition.spec.ts (1)

1783-1822: Consider breaking down HTML assertions for better maintainability.

The current approach uses string concatenation for HTML assertions, which can be brittle and hard to debug when tests fail. Consider breaking these into separate, more focused assertions:

-        expect(await html('#container')).toBe(
-          `<div><h2>I should show</h2></div>` +
-            `<h2>This is page1</h2>` +
-            `<button id="changeShowBtn">true</button>`,
-        )
+        // Verify each component separately for clearer failure messages
+        expect(await html('#container div:first-child')).toBe(`<div><h2>I should show</h2></div>`)
+        expect(await html('#container h2:nth-of-type(2)')).toBe(`<h2>This is page1</h2>`)
+        expect(await html('#container button')).toBe(`<button id="changeShowBtn">true</button>`)

This approach provides:

  • Clearer failure messages when specific elements don't match
  • Better maintainability when DOM structure changes
  • Easier debugging of test failures
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c875019 and f810dbd.

📒 Files selected for processing (3)
  • packages/runtime-core/src/components/BaseTransition.ts (1 hunks)
  • packages/runtime-core/src/renderer.ts (2 hunks)
  • packages/vue/__tests__/e2e/Transition.spec.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/vue/__tests__/e2e/Transition.spec.ts (1)
packages/vue/__tests__/e2e/e2eUtils.ts (1)
  • E2E_TIMEOUT (8-8)
🔇 Additional comments (5)
packages/runtime-core/src/components/BaseTransition.ts (1)

27-27: LGTM! Clean export for external module access.

The change from a private to public export of leaveCbKey enables the renderer to access this symbol for handling the KeepAlive + transition edge case. The symbol maintains type safety and follows Vue's architectural patterns.

packages/runtime-core/src/renderer.ts (2)

88-88: LGTM! Import updated for the KeepAlive + transition fix.

The import statement correctly includes the newly exported leaveCbKey symbol needed for the transition leave callback handling.


2073-2078: Excellent fix for the KeepAlive + transition edge case!

This logic addresses the core issue described in #13153. When a kept-alive component is moved before a v-show transition leave finishes, it ensures the leaving callback is triggered early with cancellation (true) to set the element's display style to none. This prevents components from remaining visible when they should be hidden.

The implementation is clean and follows Vue's transition patterns by:

  • Checking the _isLeaving property to identify elements in leaving state
  • Calling the leave callback with cancellation to ensure proper cleanup
  • Integrating seamlessly with the existing transition system
packages/vue/__tests__/e2e/Transition.spec.ts (2)

1726-1825: Well-structured test case for the KeepAlive + v-show transition edge case.

This test effectively covers the specific issue #13153 by:

  1. Setting up the exact scenario with KeepAlive, component switching, and v-show transitions
  2. Verifying the critical behavior where display: none is applied when switching components during a transition
  3. Testing both directions of component switching to ensure consistency

The test structure is solid and the assertions are comprehensive, checking both DOM structure and inline styles at each step.


1790-1817: Proper timing and synchronization approach.

The test correctly uses nextTick() after state changes and transitionFinish() to wait for CSS transitions, following the established patterns in the test suite. This ensures reliable test execution across different environments.

@edison1105
Copy link
Member Author

/ecosystem-ci run

@vue-bot
Copy link
Contributor

vue-bot commented Aug 20, 2025

📝 Ran ecosystem CI: Open

suite result latest scheduled
primevue success success
quasar success success
radix-vue success success
test-utils success success
vue-macros failure failure
vuetify success success
vueuse success success
vue-simple-compiler success success
vite-plugin-vue success success
vant success success
vitepress success success
router success success
pinia success success
language-tools success success
nuxt success success
vue-i18n success success

@edison1105 edison1105 merged commit 3190b17 into main Aug 20, 2025
16 checks passed
@edison1105 edison1105 deleted the edison/fix/TransitionLeaving branch August 20, 2025 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready to merge The PR is ready to be merged. scope: transition
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When Transition and keep-alive are used together, the display is incorrect
3 participants