選單
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

Vue 教程

Vue 首頁 Vue Intro Vue Directives Vue v-bind Vue v-if Vue v-show Vue v-for Vue Events Vue v-on Vue Methods Vue Event Modifiers Vue Forms Vue v-model Vue CSS Binding Vue Computed Properties Vue Watchers Vue Templates

Scaling Up

Vue 為什麼、如何及設定 Vue 第一個 SFC 頁面 Vue 元件 Vue Props Vue v-for 元件 Vue $emit() Vue Fallthrough 屬性 Vue 作用域樣式 Vue 本地元件 Vue Slots Vue v-slot Vue Scoped Slots Vue 動態元件 Vue Teleport Vue HTTP 請求 Vue 模板引用 Vue 生命週期鉤子 Vue Provide/Inject Vue 路由 Vue 表單輸入 Vue 動畫 Vue v-for 動畫 Vue 構建 Vue Composition API

Vue Reference

Vue Built-in Attributes Vue Built-in Components Vue Built-in Elements Vue Component Instance Vue Directives Vue Instance Options Vue Lifecycle Hooks

Vue 示例

Vue Examples Vue Exercises Vue Quiz Vue Server Vue Certificate

Vue <Transition> 元件


示例

使用內建的 <Transition> 元件為 <p> 元素新增動畫,該元素會隨著 v-if 的移除而消失

<Transition>
  <p v-if="exists">Hello World!</p>
</Transition>
執行示例 »

更多示例請參見下方。


定義和用法

內建的 <Transition> 元件用於在元素與 v-ifv-show 或動態元件一起新增或移除時為它們新增動畫。

元素的動畫規則寫在自動生成的類或 JavaScript 過渡鉤子中。參見下表。

<Transition> 元件的根元素只能有一個。


Props

Prop 描述
none 預設。 執行示例 »
appear 如果設定為 true,元素在首次掛載時也會進行動畫。預設值為 false 執行示例 »
mode mode="out-in" 確保當前元素離開後下一個元素再進入。 mode="in-out" 確保新元素進入後舊元素再離開。預設情況下,舊元素和新元素同時離開和進入。 執行示例 »
name 指定過渡的名稱。如果我們有多個過渡,需要給它們唯一的名稱以區分。 name="swirl" 確保 CSS 過渡類以 swirl- 開頭,而不是預設字首 v- 執行示例 »
css 布林值。 :css="false" 告訴 Vue 編譯器不使用 CSS 過渡類,僅使用 JavaScript 鉤子。設定此 prop 後,必須在 enter 和 leave 鉤子中使用 done() 回撥。 執行示例 »
type 指定是等待 'animation' 還是 'transition' 完成過渡。如果同時設定了 CSS 動畫和 CSS 過渡,並且沒有設定此 *type* prop,Vue 將檢測兩者的最長持續時間並將其用作過渡時間。
duration 指定 'enter' 和 'leave' 過渡的長度。預設是在 CSS 動畫或 CSS 過渡結束時結束。可以透過 :duration="{enter:2000, leave:1000 }"duration="1000" 來定義特定的時間。
enterFromClass
enterActiveClass
enterToClass
appearFromClass
appearActiveClass
appearToClass
leaveFromClass
leaveActiveClass
leaveToClass
使用這些 props 重新命名過渡類。

使用其中一個 prop,例如 enter-active-class="entering",意味著可以在 CSS 中將此過渡類引用為 .entering,而不是預設的 .v-enter-active。約定是在模板中使用 kebab-case 來表示 props,以符合 HTML 中屬性的寫法。

執行示例 »

CSS 過渡類

當使用 <Transition> 元件時,我們會自動獲得六個不同的 CSS 類,可以在元素新增或移除時使用它們來進行動畫。

這些類在元素新增(enter)或移除(leave)的不同階段處於活動狀態。

Transition Class 描述
v-enter-from 進入階段開始時元素的初始樣式 執行示例 »
v-enter-active 進入階段期間元素的樣式 執行示例 »
v-enter-to 進入階段結束時的元素樣式 執行示例 »
v-leave-from 離開階段開始時元素的初始樣式 執行示例 »
v-leave-active 離開階段期間元素的樣式 執行示例 »
v-leave-to 離開階段結束時的元素樣式 執行示例 »

JavaScript 過渡鉤子

上面的過渡類對應於我們可以用來執行 JavaScript 程式碼的事件。

JavaScript Event 描述
before-enter 在進入階段開始時呼叫
enter 在 'before-enter' 鉤子之後,進入階段期間呼叫 執行示例 »
after-enter 在進入過渡結束時呼叫 執行示例 »
enter-cancelled 如果進入過渡被取消,則呼叫 執行示例 »
before-leave 在離開階段開始時呼叫 執行示例 »
leave 在 'before-leave' 鉤子之後,離開階段期間呼叫 執行示例 »
after-leave 在離開過渡結束時呼叫
leave-cancelled 僅當使用 v-show 且離開階段被取消時呼叫

更多示例

示例 1

一個 <p> 元素在切換時會滑動進出。

<template>
  <h1>Add/Remove <p> Tag</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <Transition>
    <p v-if="exists">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-enter-from {
    opacity: 0;
    translate: -100px 0;
  }
  .v-enter-to {
    opacity: 1;
    translate: 0 0;
  }
  .v-leave-from {
    opacity: 1;
    translate: 0 0;
  }
  .v-leave-to {
    opacity: 0;
    translate: 100px 0;
  }
  p {
    background-color: lightgreen;
    display: inline-block;
    padding: 10px;
    transition: all 0.5s;
  }
</style>
執行示例 »

示例 2

一個 <p> 元素在 'enter' 和 'leave' 期間有不同的背景顏色。

<template>
  <h1>Add/Remove <p> Tag</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <Transition>
    <p v-if="exists">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-enter-active {
    background-color: lightgreen;
    animation: added 1s;
  }
  .v-leave-active {
    background-color: lightcoral;
    animation: added 1s reverse;
  }
  @keyframes added {
    from {
      opacity: 0;
      translate: -100px 0;
    }
    to {
      opacity: 1;
      translate: 0 0;
    }
  }
  p {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
</style>
執行示例 »

示例 3

元素以不同的方式進行動畫,使用 name prop 來區分 <Transition> 元件。

<template>
  <h1>Add/Remove <p> Tag</h1>
  <p>The second transition in this example has the name prop "swirl", so that we can keep the transitions apart with different class names.</p>
  <hr>
  <button @click="this.p1Exists = !this.p1Exists">{{btn1Text}}</button><br>
  <Transition>
    <p v-if="p1Exists" id="p1">Hello World!</p>
  </Transition>
  <hr>
  <button @click="this.p2Exists = !this.p2Exists">{{btn2Text}}</button><br>
  <Transition name="swirl">
    <p v-if="p2Exists" id="p2">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      p1Exists: false,
      p2Exists: false
    }
  },
  computed: {
    btn1Text() {
      if(this.p1Exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    },
    btn2Text() {
      if(this.p2Exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-enter-active {
    background-color: lightgreen;
    animation: added 1s;
  }
  .v-leave-active {
    background-color: lightcoral;
    animation: added 1s reverse;
  }
  @keyframes added {
    from {
      opacity: 0;
      translate: -100px 0;
    }
    to {
      opacity: 1;
      translate: 0 0;
    }
  }
  .swirl-enter-active {
    animation: swirlAdded 1s;
  }
  .swirl-leave-active {
    animation: swirlAdded 1s reverse;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  #p1, #p2 {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
  #p2 {
    background-color: lightcoral;
  }
</style>
執行示例 »

示例 4

after-enter 事件觸發一個 <div> 元素的顯示。

<template>
  <h1>JavaScript Transition Hooks</h1>
  <p>This code hooks into "after-enter" so that after the initial animation is done, a method runs that displays a red div.</p>
  <button @click="pVisible=true">Create p-tag!</button><br>
  <Transition @after-enter="onAfterEnter">
    <p v-show="pVisible" id="p1">Hello World!</p>
  </Transition>
  <br>
  <div v-show="divVisible">This appears after the "enter-active" phase of the transition.</div>
</template>

<script>
export default {
  data() {
    return {
      pVisible: false,
      divVisible: false
    }
  },
  methods: {
    onAfterEnter() {
      this.divVisible = true;
    }
  }
}
</script>

<style>
  .v-enter-active {
    animation: swirlAdded 1s;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  #p1, div {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
  #p1 {
    background-color: lightgreen;
  }
  div {
    background-color: lightcoral;
  }
</style>
執行示例 »

示例 5

一個切換按鈕觸發 enter-cancelled 事件。

<template>
  <h1>The 'enter-cancelled' Event</h1>
  <p>Click the toggle button again before the enter animation is finished to trigger the 'enter-cancelled' event.</p>
  <button @click="pVisible=!pVisible">Toggle</button><br>
  <Transition @enter-cancelled="onEnterCancelled">
    <p v-if="pVisible" id="p1">Hello World!</p>
  </Transition>
  <br>
  <div v-if="divVisible">You interrupted the "enter-active" transition.</div>
</template>

<script>
export default {
  data() {
    return {
      pVisible: false,
      divVisible: false
    }
  },
  methods: {
    onEnterCancelled() {
      this.divVisible = true;
    }
  }
}
</script>

<style>
  .v-enter-active {
    animation: swirlAdded 2s;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 720deg;
      scale: 1;
    }
  }
  #p1, div {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
  #p1 {
    background-color: lightgreen;
  }
  div {
    background-color: lightcoral;
  }
</style>
執行示例 »

示例 6

appear prop 會在頁面載入後立即開始 <p> 元素的動畫。

<template>
  <h1>The 'appear' Prop</h1>
  <p>The 'appear' prop starts the animation when the p tag below is rendered for the first time as the page opens. Without the 'appear' prop, this example would have had no animation.</p>
  <Transition appear>
    <p id="p1">Hello World!</p>
  </Transition>
</template>

<style>
  .v-enter-active {
    animation: swirlAdded 1s;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  #p1 {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
    background-color: lightgreen;
  }
</style>
執行示例 »

示例 7

透過 'enter' 和 'leave' 的動畫來翻閱影像。在舊影像移除之前新增新影像。

<template>
  <h1>Transition Between Elements</h1>
  <p>Click the button to get a new image.</p>
  <p>The new image is added before the previous is removed. We will fix this in the next example with mode="out-in".</p>
  <button @click="newImg">Next image</button><br>
  <Transition>
    <img src="/img_pizza.svg" v-if="imgActive === 'pizza'">
    <img src="/img_apple.svg" v-else-if="imgActive === 'apple'">
    <img src="/img_cake.svg" v-else-if="imgActive === 'cake'">
    <img src="/img_fish.svg" v-else-if="imgActive === 'fish'">
    <img src="/img_rice.svg" v-else-if="imgActive === 'rice'">
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      imgActive: 'pizza',
      imgs: ['pizza', 'apple', 'cake', 'fish', 'rice'],
      indexNbr: 0
    }
  },
  methods: {
    newImg() {
      this.indexNbr++;
      if(this.indexNbr >= this.imgs.length) {
        this.indexNbr = 0;
      }
      this.imgActive = this.imgs[this.indexNbr];
    }
  }
}
</script>

<style>
  .v-enter-active {
    animation: swirlAdded 1s;
  }
  .v-leave-active {
    animation: swirlAdded 1s reverse;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  img {
    width: 100px;
    margin: 20px;
  }
  img:hover {
    cursor: pointer;
  }
</style>
執行示例 »

示例 8

透過 'enter' 和 'leave' 的動畫來翻閱影像。 mode="out-in" 防止在新影像新增之前移除舊影像。

<template>
  <h1>mode="out-in"</h1>
  <p>Click the button to get a new image.</p>
  <p>With mode="out-in", the next image is not added until the current image is removed. Another difference from the previous example, is that here we use computed prop instead of a method.</p>
  <button @click="indexNbr++">Next image</button><br>
  <Transition mode="out-in">
    <img src="/img_pizza.svg" v-if="imgActive === 'pizza'">
    <img src="/img_apple.svg" v-else-if="imgActive === 'apple'">
    <img src="/img_cake.svg" v-else-if="imgActive === 'cake'">
    <img src="/img_fish.svg" v-else-if="imgActive === 'fish'">
    <img src="/img_rice.svg" v-else-if="imgActive === 'rice'">
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      imgs: ['pizza', 'apple', 'cake', 'fish', 'rice'],
      indexNbr: 0
    }
  },
  computed: {
    imgActive() {
      if(this.indexNbr >= this.imgs.length) {
        this.indexNbr = 0;
      }
      return this.imgs[this.indexNbr];
    }
  }
}
</script>

<style>
  .v-enter-active {
    animation: swirlAdded 0.7s;
  }
  .v-leave-active {
    animation: swirlAdded 0.7s reverse;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  img {
    width: 100px;
    margin: 20px;
  }
  img:hover {
    cursor: pointer;
  }
</style>
執行示例 »

示例 9

元件之間的切換被動畫化。

<template>
  <h1>Transition with Dynamic Components</h1>
  <p>The Transition component wraps around the dynamic component so that the switching can be animated.</p>
  <button @click="toggleValue = !toggleValue">Switch component</button>
  <Transition mode="out-in">
    <component :is="activeComp"></component>
  </Transition>
</template>

<script>
  export default {
    data () {
      return {
        toggleValue: true
      }
    },
    computed: {
      activeComp() {
        if(this.toggleValue) {
          return 'comp-one'
        }
        else {
          return 'comp-two'
        }
      }
    }
  }
</script>

<style>
  .v-enter-active {
    animation: slideIn 0.5s;
  }
  @keyframes slideIn {
    from {
      translate: -200px 0;
      opacity: 0;
    }
    to {
      translate: 0 0;
      opacity: 1;
    }
  }
  .v-leave-active {
    animation: slideOut 0.5s;
  }
  @keyframes slideOut {
    from {
      translate: 0 0;
      opacity: 1;
    }
    to {
      translate: 200px 0;
      opacity: 0;
    }
  }
  #app {
    width: 350px;
    margin: 10px;
  }
  #app > div {
    border: solid black 2px;
    padding: 10px;
    margin-top: 10px;
  }
</style>
執行示例 »

示例 10

元件之間的切換被動畫化。

<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>
執行示例 »

示例 11

使用 enterActiveClass prop 將 'v-enter-active' CSS 類重新命名為 'entering'。

<template>
  <h1>The 'enterActiveClass' Prop</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <Transition enter-active-class="entering">
    <p v-if="exists">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .entering {
    background-color: lightgreen;
    animation: added 1s;
  }
  .v-leave-active {
    background-color: lightcoral;
    animation: added 1s reverse;
  }
  @keyframes added {
    from {
      opacity: 0;
      translate: -100px 0;
    }
    to {
      opacity: 1;
      translate: 0 0;
    }
  }
  p {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
</style>
執行示例 »

相關頁面

Vue 教程: Vue 動畫

Vue 教程: Vue v-for 動畫

Vue 參考: Vue <TransitionGroup> 元件


×

聯絡銷售

如果您想將 W3Schools 服務用於教育機構、團隊或企業,請傳送電子郵件給我們
sales@w3schools.com

報告錯誤

如果您想報告錯誤,或想提出建議,請傳送電子郵件給我們
help@w3schools.com

W3Schools 經過最佳化,旨在方便學習和培訓。示例可能經過簡化,以提高閱讀和學習體驗。教程、參考資料和示例會不斷審查,以避免錯誤,但我們無法保證所有內容的完全正確性。使用 W3Schools 即表示您已閱讀並接受我們的使用條款Cookie 和隱私政策

版權所有 1999-2024 Refsnes Data。保留所有權利。W3Schools 由 W3.CSS 提供支援