Like Vue‘s Teleport component, but different.
npm install teleporte component, but different.portal-vue to built-in Vue‘s component and couldn't make it work with TransitionGroup. After I decided to keep portal-vue in the project, as I needed the extra features, but
there were also some caveats
with its implementation and I start to wonder how hard would be to implement a
very minimalistic version of a teleport myself.
1. Try using built-in Vue‘s first. No point in bringing a 3rd party
lib into your app when you only need simple teleport capabilities, like sending
modals/dropdowns to end of .
1. Use teleporte if you need good support for in-app dynamic transportation of
content, with conditional/deferred rendering of both origin/target; when
custom TransitionGroup is required at target level or when provide/inject
is heavily used.
1. Use portal-vue for everything else.
| Quirks list | Vue's | portal-vue | teleporte |
|----------------------------------------------------------|--------------------|--------------|----------------------|
| Works when target is mounted after teleport origin | x⁵ | ✔️ | ✔️ |
| Teleported content can use provide/inject origin context | ✔️ | x | ✔️ |
| Teleport Target can use | x | ✔️¹ | ✔️¹ |
| use of $parent | (TBD) | x | (TBD) |
| vue-router view | (TBD) | x | x (will not support) |
| use of $refs | ✔️ | ✔️² | ✔️³ |
| SSR support | ✔️⁴ | ✔️⁴ | ✔️⁴ |
##### Footnotes
1. Requires usage of target component #default slot bindings and loop over
exposed vnodes directly into TransitionGroup default slot
1. after nextTick (see caveats in docs)
1. to assert the need for nextTick
1. Yes with caveats (see SSR Section)
1. Will be supported without workarounds in 3.5.x minor
``bash`npm | yarn
pnpm install teleporte
>[!WARNING]
>This package requires vue@^3.2.0 to be installed.
Then Import the components.
`html
import { TeleportOrigin, TeleportTarget } from 'teleporte'
This slot content will be rendered wherever the
is located.
`
`js
import { TeleportPlugin } from 'teleporte'
import { createApp } from 'vue'
const app = createApp()
app.use(TeleportPlugin)
// exposes Teleporte and TeleportTarget as global components
`
html
import { Teleporte, TeleporteTarget } from 'teleporte'
This slot content will be rendered wherever the
with name 'destination'
is located.
v-for="teleport in teleported"
:key="teleport.key"
:is="teleport.component"
/>
`
$3
#### cross-request-state-pollution
TL;DR we use a singleton pattern for storing
teleports state so the module state is preserved on each request which would lead to content duplication. We prevent that within library code.
#### Hydration mismatches
Since the content will not render on server, you'll get a warning from Vue. The same caveat is present in the other "teleport" implementations so the workarounds are the same:
1. defer
mount with a ref at onMounted hook + v-if
1. Your SSR framework (like nuxt) will probably provide a component, so wrap inside it
1. There are external component implementations out there as well or you can roll your own.See:
- https://vuejs.org/guide/scaling-up/ssr#cross-request-state-pollution
- https://vuejs.org/guide/scaling-up/ssr#teleports
- https://portal-vue.linusb.org/guide/ssr.html
Contribute
See the guide at CONTRIBUTING.mdGoals
1. To be deprecated if Vue‘s adds fixes to the current quirks :)
- [x] https://github.com/vuejs/core/issues/2015
- [ ] https://github.com/vuejs/core/issues/4737
- [ ] https://github.com/vuejs/core/issues/5836#issuecomment-2230343828
- [ ] https://github.com/vuejs/core/issues/5864
1. While that does not happen, this project aims to be a just minimalistic enhanced
version of :
- bundle size to be kept below around ≈1.2KB gzip
- No unnecessary features: it should do one thing and do it well, move content
between target and origin without quirks. Credits
portal-vue, the main inspiration
for this package implementation
- Vue‘s