App.vue
main.js
 
<template>
  <h1>The :css="false" Prop</h1>
  <p>With the 'css' prop set to 'false', we tell the compiler that JavaScript hooks are used instead of CSS transition classes.</p>
  <p>When we use :css="false", we must call done() inside the 'enter' and the 'leave' hooks to tell the browser when those transitions are finished.</p>
  <button @click="pVisible=!pVisible">Toggle</button>
  <div>
    <Transition
      :css="false" 
      @enter="onEnter"
      @after-enter="onAfterEnter"
      @before-leave="onBeforeLeave"
      @leave="onLeave"
    >
      <p 
        v-if="pVisible"
        id="p1">
        Hello World!
      </p>
    </Transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      pVisible: false
    }
  },
  methods: {
    onEnter(el,done) {
      let pos = 0;
      window.requestAnimationFrame(frame);
      function frame() {
        if (pos > 150) {
          done();
        } else {
          pos++; 
          el.style.left = pos + "px"; 
          window.requestAnimationFrame(frame);
        }
      }
    },
    onAfterEnter(el) {
      el.style.backgroundColor = "yellow";
    },
    onBeforeLeave(el) {
      el.style.backgroundColor = "lightgreen";
    },
    onLeave(el,done) {
      let pos = 150;
      window.requestAnimationFrame(frame);
      function frame() {
        if (pos < 0) {
          done();
        }
        else {
          pos--;
          el.style.left = pos + "px"; 
          window.requestAnimationFrame(frame);
        }
      }
    }
  }
}
</script>

<style>
  #p1 {
    position: absolute;
    padding: 10px;
    border: dashed black 1px;
    background-color: lightgreen;
  }
  #app > div {
    position: relative;
    background-color: coral;
    width: 300px;
    height: 300px;
    border: dashed black 1px;
    margin-top: 20px;
  }
</style>                  
import { createApp } from 'vue'

import App from './App.vue'

const app = createApp(App)
app.mount('#app')
                  
http://localhost:5173/