Skip to content

Using built-in components with render and :is #946

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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions src/api/built-in-components.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Built-In Components

Built-in components can be used directly in templates without needing to be registered.

The `<keep-alive>`, `<transition>`, `<transition-group>`, and `<teleport>` components can all be tree-shaken by bundlers, so that they are only included in the build if they're used. They can also be imported explicitly if you need direct access to the component itself:

```js
// CDN build of Vue
const { KeepAlive, Teleport, Transition, TransitionGroup } = Vue
```

```js
// ESM build of Vue
import { KeepAlive, Teleport, Transition, TransitionGroup } from 'vue'
```

`<component>` and `<slot>` are component-like features of template syntax. They are not true components and they can't be imported like the components shown above.

## component

- **Props:**
Expand All @@ -10,8 +26,6 @@

A "meta component" for rendering dynamic components. The actual component to render is determined by the `is` prop. An `is` prop as a string could be either an HTML tag name or a Component name.

- **Example:**

```html
<!-- a dynamic component controlled by -->
<!-- the `componentId` property on the vm -->
Expand All @@ -27,6 +41,27 @@
<component :is="href ? 'a' : 'span'"></component>
```

The built-in components `KeepAlive`, `Transition`, `TransitionGroup`, and `Teleport` can all be passed to `is`, but you must register them if you want to pass them by name. For example:

```js
const { Transition, TransitionGroup } = Vue

const Component = {
components: {
Transition,
TransitionGroup
},

template: `
<component :is="isGroup ? 'TransitionGroup' : 'Transition'">
...
</component>
`
}
```

Registration is not required if you pass the component itself to `is` rather than its name.

- **See also:** [Dynamic Components](../guide/component-dynamic-async.html)

## transition
Expand Down
16 changes: 16 additions & 0 deletions src/guide/render-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,22 @@ render () {

[`resolveDirective`](/api/global-api.html#resolvedirective) is the same function that templates use internally to resolve directives by name. That is only necessary if you don't already have direct access to the directive's definition object.

### Built-in Components

[Built-in components](/api/built-in-components.html) such as `<keep-alive>`, `<transition>`, `<transition-group>`, and `<teleport>` are not registered globally by default. This allows bundlers to perform tree-shaking, so that the components are only included in the build if they are used. However, that also means we can't access them using `resolveComponent` or `resolveDynamicComponent`.

Templates have special handling for those components, automatically importing them when they are used. When we're writing our own `render` functions, we need to import them ourselves:

```js
const { h, KeepAlive, Teleport, Transition, TransitionGroup } = Vue

// ...

render () {
return h(Transition, { mode: 'out-in' }, /* ... */)
}
```

## JSX

If we're writing a lot of `render` functions, it might feel painful to write something like this:
Expand Down