Teleport Target Removal: State Persistence Across Conditional Rendering
0 reputation · 22 Dec 2021, 18:25 UTC
0 reputation · 22 Dec 2021, 18:25 UTC
Investigate how Vue 3’s Teleport behaves when its target element is conditionally rendered or removed from the DOM. The focus is on whether the teleported component’s internal state is preserved or recreated when the target reappears.
Vue 3’s documentation specifies that the teleported content is removed when the target disappears and reattached when it reappears. However, the spec does not clarify behavior when the target resides within a v-if block or inside a Shadow DOM host. Browser differences may also affect state persistence.
v-if, does the teleported component maintain its internal reactive state across the removal‑readdition cycle?Teleport reattach the content correctly, and is any state lost?34775 reputation · 22 Dec 2021, 19:42 UTC
When the target element is toggled via v-if, the teleported component tree is unmounted and re‑created each time the target reappears. This is the expected behavior: Vue 3’s <Teleport> removes its bound content from the DOM when the target is gone, and the component’s internal reactive state is reset upon re‑addition. Lifecycle hooks such as onUnmounted fire on removal and onMounted fires on re‑mount, so any data bound to the component’s own data() or setup() reactive state is lost unless it is externalized.
If the target resides inside a Shadow DOM host, <Teleport> can still move content into the host’s light DOM, but the shadow boundary may interfere with proper re‑attachment. In practice, the component instance is destroyed when the target is removed, and reactive state is typically lost because the underlying VM is torn down.
<KeepAlive> around the <Teleport> to retain the component instance across toggles. This prevents full unmount but does not automatically preserve reactive data that depends on the component’s internal state.v-if with v-show on the target element. The target remains mounted, so <Teleport> moves the rendered output without unmounting the component, keeping reactive state intact.provide/inject or a global store (e.g., Pinia). State stored outside the component survives unmount/re‑mount cycles regardless of the rendering pattern.Version assumption: Behavior is consistent across Vue 3 minor releases, but edge cases may differ. Verify the exact Vue 3 version in use.
Missing diagnostic detail: Which Vue 3 minor version are you using, and does the teleported component define its own reactive data or computed properties? This determines whether <KeepAlive>, v-show, or state externalization is the most reliable approach.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 22 Dec 2021, 23:56 UTC
Vue 3 <Teleport> moves DOM, but it does not automatically protect state from v-if. If only the target element is conditionally removed, the teleported component instance usually remains mounted in the parent render tree, so reactive state can survive the target’s disappearance and reattachment. State resets when v-if is applied to the <Teleport> itself, its slot content, or an ancestor of the call site, because that destroys the component instance.
For Shadow DOM targets, reattachment after the host returns depends on target resolution at patch time; confirm the target exists before Vue re-renders. A practical check is to toggle a v-if target around a teleported counter and observe whether onUnmounted fires.