Skip to content

Vue

@awesome-reveal/vue has two APIs with the same options:

  • The v-reveal directive animates your own element or component, with no wrapper.
  • The Reveal component renders one element and animates it.
Terminal window
pnpm add @awesome-reveal/vue

The package needs Vue 3.5 or later.

Import path Contents
@awesome-reveal/vue The v-reveal directive, the Reveal component, and their types.
@awesome-reveal/vue/keyframes The built-in keyframes, defineKeyframes, and their types.

@awesome-reveal/vue/keyframes does not import Vue.

v-reveal animates the element that it is on. Its value is an object with the reveal options. On a component, it animates the root element of the component:

<script setup>
import { vReveal } from "@awesome-reveal/vue";
import { fade, slide } from "@awesome-reveal/vue/keyframes";
const fromLeft = slide({ direction: "left" });
</script>
<template>
<p v-reveal>I gently appear as I enter the viewport</p>
<section v-reveal="{ keyframes: fromLeft, duration: 800 }">…</section>
<article v-reveal="{ keyframes: fade(), threshold: 0.3 }">…</article>
</template>

Without keyframes, the element fades in and moves up, as with slide().

While the element is hidden, it has an inline opacity: 0 and data-reveal="hidden". The reveal removes data-reveal and restores the inline opacity that the element had when v-reveal mounted. With SSR, the server markup replaces an inline opacity of your own, so set it in a class.

In <script setup>, the import of vReveal makes v-reveal available. To use it in all components, register it on the app:

import { createApp } from "vue";
import { vReveal } from "@awesome-reveal/vue";
import App from "./App.vue";
createApp(App).directive("reveal", vReveal).mount("#app");
// Types v-reveal in the templates of all components.
declare module "vue" {
interface GlobalDirectives {
vReveal: typeof vReveal;
}
}

Reveal renders one element around its default slot. as sets the tag, and the default is div. Reveal gives its other attributes to that element:

<script setup>
import { Reveal } from "@awesome-reveal/vue";
import { slide } from "@awesome-reveal/vue/keyframes";
</script>
<template>
<Reveal as="section" :keyframes="slide()" class="hero" id="intro">
<h1>Welcome</h1>
</Reveal>
</template>

Reveal keeps your own style. Until the reveal, the hidden opacity: 0 overrides your opacity.

The children animate together. To animate them one after the other, use stagger.

Reveal accepts the reveal options as props, and v-reveal accepts them as one object.

once and when are optional. Without a value, they keep the default behavior: <Reveal> reveals once, and observes the viewport.

For the rules of when, such as the flash after hydration, see Control the reveal manually. For the effect of a changed option, see Option changes.

When Vue replaces the element of v-reveal, for example with a new key or tag, the new element starts a new reveal. Reveal keeps its state when as changes and does not play again.

With when, your code controls the reveal, and nothing observes the viewport:

  • :when="false" hides the element.
  • :when="true" reveals the element and plays the animation.
  • A change from true to false hides the element again.
<Reveal as="ul" :when="data !== undefined" :stagger="50">
<li v-for="item in data" :key="item.id">{{ item.name }}</li>
</Reveal>

With when, threshold, rootMargin and once have no effect.

@awesome-reveal/vue exports these types:

  • RevealProps: the props of Reveal.
  • RevealOptions: the reveal options, for v-reveal.

@awesome-reveal/vue/keyframes exports the keyframes types, such as KeyframesFactory and SlideOptions. See Keyframes.

On the server, v-reveal and Reveal render the element hidden, with opacity: 0 and data-reveal="hidden", unless when is true. The animation starts in the browser, when the element enters the viewport. If JavaScript does not run, the element stays hidden. To show it, add the <noscript> style.

On the server, v-reveal also renders data-allow-mismatch="style". The client render of the element does not have the hidden style. Without this attribute, a style binding on the element causes a hydration mismatch warning. The attribute allows a style mismatch on that element only.