mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
feat(nitro): support for rendering ssr teleports to body (#3909)
Co-authored-by: pooya parsa <pyapar@gmail.com>
This commit is contained in:
parent
ade3378a00
commit
fdd38f958c
@ -16,6 +16,7 @@
|
||||
"vue/multi-word-component-names": "off",
|
||||
"vue/one-component-per-file": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/no-multiple-template-root": "off",
|
||||
"jsdoc/require-jsdoc": "off",
|
||||
"jsdoc/require-param": "off",
|
||||
"jsdoc/require-returns": "off",
|
||||
|
34
docs/content/3.docs/1.usage/10.teleports.md
Normal file
34
docs/content/3.docs/1.usage/10.teleports.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Teleports
|
||||
|
||||
Vue 3 provides the [`<Teleport>` component](https://vuejs.org/guide/built-ins/teleport.html) which allows content to be rendered elsewhere in the DOM, outside of the Vue application.
|
||||
|
||||
The `to` target of `<Teleport>` expects a CSS selector string or an actual DOM node. Nuxt currently has SSR support for teleports to `body` only, with client-side support for other targets using a `<ClientOnly>` wrapper.
|
||||
|
||||
## Example: body teleport
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<button @click="open = true">
|
||||
Open Modal
|
||||
</button>
|
||||
<Teleport to="body">
|
||||
<div v-if="open" class="modal">
|
||||
<p>Hello from the modal!</p>
|
||||
<button @click="open = false">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Example: client-side teleport
|
||||
|
||||
```vue
|
||||
<ClientOnly>
|
||||
<Teleport to="#some-selector">
|
||||
<!-- content -->
|
||||
</Teleport>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
```
|
15
docs/content/4.examples/1.app/teleport.md
Normal file
15
docs/content/4.examples/1.app/teleport.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
template: Example
|
||||
---
|
||||
|
||||
# Teleport
|
||||
|
||||
Vue 3 provides the [`<Teleport>` component](https://vuejs.org/guide/built-ins/teleport.html) which allows content to be rendered elsewhere in the DOM, outside of the Vue application.
|
||||
|
||||
This example shows how to use the `<Teleport>` with client-side and server-side rendering.
|
||||
|
||||
::alert{type=info icon=👉}
|
||||
Learn more about [teleports](/docs/usage/teleports).
|
||||
::
|
||||
|
||||
::sandbox{repo="nuxt/framework" branch="main" dir="examples/app/teleport" file="app.vue"}
|
22
examples/app/teleport/app.vue
Normal file
22
examples/app/teleport/app.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<NuxtExampleLayout example="app/teleport">
|
||||
<div>
|
||||
<!-- SSR Teleport -->
|
||||
<Teleport to="body">
|
||||
SSR Teleport
|
||||
</Teleport>
|
||||
|
||||
<!-- Client Teleport -->
|
||||
<ClientOnly>
|
||||
<Teleport to="body">
|
||||
<div>
|
||||
Hello from a client-side teleport!
|
||||
</div>
|
||||
</Teleport>
|
||||
</ClientOnly>
|
||||
|
||||
<!-- Modal Example -->
|
||||
<MyModal />
|
||||
</div>
|
||||
</NuxtExampleLayout>
|
||||
</template>
|
34
examples/app/teleport/components/MyModal.vue
Normal file
34
examples/app/teleport/components/MyModal.vue
Normal file
@ -0,0 +1,34 @@
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
open: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NButton @click="open = true">
|
||||
Open Modal
|
||||
</NButton>
|
||||
<Teleport to="body">
|
||||
<NCard v-if="open" class="modal p4">
|
||||
<p>Hello from the modal!</p>
|
||||
<NButton @click="open = false">
|
||||
Close
|
||||
</NButton>
|
||||
</NCard>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.modal {
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
top: 20%;
|
||||
left: 50%;
|
||||
width: 300px;
|
||||
margin-left: -150px;
|
||||
}
|
||||
</style>
|
7
examples/app/teleport/nuxt.config.ts
Normal file
7
examples/app/teleport/nuxt.config.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineNuxtConfig } from 'nuxt3'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
modules: [
|
||||
'@nuxt/ui'
|
||||
]
|
||||
})
|
13
examples/app/teleport/package.json
Normal file
13
examples/app/teleport/package.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "example-teleport",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nuxi build",
|
||||
"dev": "nuxi dev",
|
||||
"start": "nuxi preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/ui": "npm:@nuxt/ui-edge@latest",
|
||||
"nuxt3": "latest"
|
||||
}
|
||||
}
|
3
examples/app/teleport/tsconfig.json
Normal file
3
examples/app/teleport/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|
@ -158,6 +158,7 @@ async function renderHTML (payload, rendered, ssrContext) {
|
||||
HEAD: headTags +
|
||||
rendered.renderResourceHints() + rendered.renderStyles() + (ssrContext.styles || ''),
|
||||
BODY_ATTRS: bodyAttrs,
|
||||
BODY_PREPEND: ssrContext.teleports?.body || '',
|
||||
APP: bodyScriptsPrepend + html + state + rendered.renderScripts() + bodyScripts
|
||||
})
|
||||
}
|
||||
@ -171,7 +172,7 @@ function _interopDefault (e) {
|
||||
}
|
||||
|
||||
function cachedImport <M> (importer: () => Promise<M>) {
|
||||
return cachedResult(() => importer().then(_interopDefault))
|
||||
return cachedResult(() => importer().then(_interopDefault)) as () => Promise<M>
|
||||
}
|
||||
|
||||
function cachedResult <T> (fn: () => Promise<T>): () => Promise<T> {
|
||||
|
@ -80,7 +80,7 @@ export const appViewTemplate = {
|
||||
{{ HEAD }}
|
||||
</head>
|
||||
|
||||
<body {{ BODY_ATTRS }}>
|
||||
<body {{ BODY_ATTRS }}>{{ BODY_PREPEND }}
|
||||
{{ APP }}
|
||||
</body>
|
||||
|
||||
|
@ -10592,6 +10592,15 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"example-teleport@workspace:examples/app/teleport":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "example-teleport@workspace:examples/app/teleport"
|
||||
dependencies:
|
||||
"@nuxt/ui": "npm:@nuxt/ui-edge@latest"
|
||||
nuxt3: latest
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"example-test@workspace:examples/advanced/test":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "example-test@workspace:examples/advanced/test"
|
||||
|
Loading…
Reference in New Issue
Block a user