<ViewTransition>
component
The <ViewTransition>
component provides a way to animate transition between two states using View Transitions API.
It's built on top of the built-in Vue <Transition>
component. So the default slot uses the same rules for its content as in the <Transition>
component: it only supports a single element or component as its slot content. If the content is a component, the component must also have only one single root element.
Transition name
The name
property is optional and allows you to specify view-transition-name
css property for the slot element, so you can define custom transition animations instead of using User-Agent's default cross-fade transition. Also, view-transition-${name}
css class is added to the <html>
during the transition.
You can apply view-transition-name
css property to the slot contents on your own though.
In case name
property is not provided, <ViewTransition>
anyway will apply unique view-transition-name
for each transition, to ensure that the slot contents are going to be animated in a separate ViewTransition layer, not as a root layer.
Single child and :key
attribute
Similar to the <Transition>
component, <ViewTransition>
requires a single child element or component as its slot content. It means that you can use:
- multiple elements with
v-if/v-else-if/v-else
statements - single element with
v-if
statement - single element with
:key
attribute
Here is an example with :key
attribute:
Not scoped yet
document.startViewTransition
is designed as a document-wide transition API. It means, when you want to animate a small piece of UI in the document, the whole document will be involved in the transition anyway. And the document will be not interactive during the transition – it's by design of this API.
Scoped view transitions probably will be supported in CSS View Transitions Module Level 2 (https://github.com/w3c/csswg-drafts/issues/9890, https://www.w3.org/TR/css-view-transitions-2/), but for now, we can use a workaround to disable the root layer transition:
html::view-transition-old(root) {
display: none;
}
html::view-transition-new(root) {
animation: none;
}
This way we are mimicking a scoped view transition, but still the document will be non-interactive during the transition.
Take a look at the example below. To see the difference, check/uncheck checkbox "Disable root's transition animation" and press "Toggle". When the checkbox is unchecked you should see a cross-fade animation of the bouncing ball. Don't see? Try "Toggle (slow)" then.
<ViewTransition>
🌸</ViewTransition>
🏀 Multiple transitions
You can define multiple <ViewTransition>
components, which can start at the same time. <ViewTransition>
debounces document.startViewTransition()
calls within one microtask.
You can also define two <ViewTransition>
components with the same name
property. This way you achieve a moving animation.
Not supported?
If the browser is not supporting View Transitions API yet, the <ViewTransition>
component will fallback to the instant transition without animation.
More examples
Please refer to the Examples section for more examples of using <ViewTransition>
.
API
Props
name?: string
(default:undefined
)Defines the name of the view transition. If not provided, a default unique name will be used.
This applies
view-transition-name: ${name}
css property on the slot element during the transition. Also,view-transition-${name}
css class will be added to the<html>
tag during the transition.appear?: boolean
(default:false
)Apply a transition on the initial render.
https://vuejs.org/guide/built-ins/transition#transition-on-appear
Events
@before-transition({ leaveElement: Element | null; enterElement: Element | null })
Emitted just before
document.startViewTransition()
is called.@transition({ leaveElement: Element | null; enterElement: Element | null })
Emitted after
document.startViewTransition()
is called, duringupdateCallback
execution.@completed({ leaveElement: Element | null; enterElement: Element | null })
Emitted after the transition is finished, once
viewTransition.finished
is resolved.
Slots
default(): VNode
Applies the same rules as for the
<Transition>
component: a single element or component. If the content is a component, the component must also have only one single root element.https://vuejs.org/guide/built-ins/transition.html#the-transition-component