diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index 25920a938a..d9e6e31338 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -46,6 +46,7 @@ const sidebar = { children: [ '/guide/mixins', '/guide/custom-directive', + '/guide/teleport', '/guide/render-function', '/guide/plugins', '/guide/composition-api-introduction' @@ -54,9 +55,7 @@ const sidebar = { { title: 'Tooling', collapsable: false, - children: [ - '/guide/single-file-component' - ] + children: ['/guide/single-file-component'] }, { title: 'Scaling Up', @@ -71,9 +70,7 @@ const sidebar = { { title: 'Tooling', collapsable: false, - children: [ - '/guide/testing' - ] + children: ['/guide/testing'] }, { title: 'Migration to Vue 3', diff --git a/src/api/built-in-components.md b/src/api/built-in-components.md index 4b576b77a3..c59f326b8f 100644 --- a/src/api/built-in-components.md +++ b/src/api/built-in-components.md @@ -212,3 +212,32 @@ For detailed usage, see the guide section linked below. - **See also:** [Content Distribution with Slots](../guide/component-basics.html#content-distribution-with-slots) + +## teleport + +- **Props:** + + - `to` - `string`. Required prop, has to be a valid query selector, or an HTMLElement (if used in a browser environment). Specifies a target element where `` content will be moved + + ```html + + + + + + + + + ``` + + - `disabled` - `boolean`. This optional prop can be used to disable the ``'s functionality, which means that its slot content will not be moved anywhere and instead be rendered where you specified the `` in the surrounding parent component. + + ```html + + + ``` + + Notice that this will move the actual DOM nodes instead of being destroyed and recreated, and it will keep any component instances alive as well. All stateful HTML elements (i.e. a playing video) will keep their state. + +- **See also:** [Teleport component](../guide/teleport.html#teleport) diff --git a/src/guide/teleport.md b/src/guide/teleport.md new file mode 100644 index 0000000000..b03ec2b9cd --- /dev/null +++ b/src/guide/teleport.md @@ -0,0 +1,104 @@ +# Teleport + +Vue encourages us to build our UIs by encapsulating UI and related behavior into components. We can nest them inside one another to build a tree that makes up an application UI. + +However, sometimes a part of a component's template belongs into this component logically, while from a technical point of view, it would be preferable to move this part of the template somewhere else in the DOM, outside of Vue app. For example, due to styling requirements, we want to move `

` from it's deeply nested position to the `

` with `id="endofbody"` + +```html + +
+

Move the #content with the portal component

+
+

+ This should be moved to #endofbody. +

+ This content should be nested +
+
+
+ +``` + +To do so, we can use Vue's built-in `` component: + +```html + +
+

Move the #content with the portal component

+
+ +

+ This should be moved to #endofbody. +

+
+ This content should be nested +
+
+
+ +``` + +As a result, we will have `teleport` content moved in the rendered DOM tree: + +

+ See the Pen + Teleport by Vue (@Vue) + on CodePen. +

+ + +As you can see, all of the children of `` will be appended to `
`. + +## Using with Vue components + +If `` contains a Vue component, it will remain a logical child component of the ``'s parent: + +```js +const app = Vue.createApp({ + template: ` +

Root instance

+ + ` +}) + +app.component('parent-component', { + template: ` +

This is a parent component

+ + + + ` +}) + +app.component('child-component', { + props: ['name'], + template: ` +
Hello, {{ name }}
+ ` +}) +``` + +In this case, even when `child-component` is rendered in the different place, it will remain a child of `parent-component` and will receive a `name` prop from it. + +This also means that injections from a parent component work as expected, and that the child component will be nested below the parent component in the Vue Devtools, instead of being placed where the actual content moved to. + +## Using multiple teleports on the same target + +A common use case scenario would be a reusable `` component of which there might be multiple instances active at the same time. For this kind of scenario, multiple `` components can mount their content to the same target element. The order will be a simple append - later mounts will be located after earlier ones within the target element. + +```html + +
A
+
+ +
B
+
+ + +
+
A
+
B
+
+``` + +You can check `` component options in the [API reference](../api/built-in-components.html#teleport)