選單
×
   ❮   
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 透傳屬性 Vue 作用域樣式 Vue 本地元件 Vue 插槽 Vue v-slot Vue 作用域插槽 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 動畫

Vue 內建的 <Transition> 元件可以幫助我們在元素使用 v-ifv-show 或動態元件新增或移除時執行動畫。

在其他情況下,使用純 CSS 過渡和動畫也沒有問題。

CSS 過渡和動畫簡介

本教程的這部分需要您瞭解基本的 CSS 動畫過渡知識。

但在我們使用 Vue 特有的內建 <Transition> 元件建立動畫之前,讓我們來看兩個如何使用純 CSS 動畫和過渡與 Vue 結合的示例。

示例

App.vue:

<template>
  <h1>Basic CSS Transition</h1>
  <button @click="this.doesRotate = true">Rotate</button>
  <div :class="{ rotate: doesRotate }"></div>
</template>

<script>
export default {
  data() {
    return {
      doesRotate: false
    }
  }
}
</script>

<style scoped>
  .rotate {
    rotate: 160deg;
    transition: rotate 1s;
  }
  div {
    border: solid black 2px;
    background-color: lightcoral;
    width: 60px;
    height: 60px;
  }
  h1, button, div {
    margin: 10px;
  }
</style>
執行示例 »

在上一個示例中,我們使用 v-bind<div> 標籤添加了一個 class 以使其旋轉。旋轉耗時 1 秒是因為它透過 CSS 的 transition 屬性定義的。

在下面的示例中,我們展示瞭如何使用 CSS 的 animation 屬性來移動一個物件。

示例

App.vue:

<template>
  <h1>Basic CSS Animation</h1>
  <button @click="this.doesMove = true">Start</button>
  <div :class="{ move: doesMove }"></div>
</template>

<script>
export default {
  data() {
    return {
      doesMove: false
    }
  }
}
</script>

<style scoped>
  .move {
    animation: move .5s alternate 4 ease-in-out;
  }
  @keyframes move {
    from {
      translate: 0 0;
    }
    to {
      translate: 70px 0;
    }
  }
  div {
    border: solid black 2px;
    background-color: lightcoral;
    border-radius: 50%;
    width: 60px;
    height: 60px;
  }
  h1, button, div {
    margin: 10px;
  }
</style>
執行示例 »

The <Transition> 元件

在上面兩個示例中,使用純 CSS 過渡和動畫沒有問題。

但幸運的是,Vue 提供了內建的 <Transition> 元件,當元素使用 v-ifv-show 被新增到我們的應用程式或從應用程式中移除時,我們可以用它來動畫化,因為這用純 CSS 動畫很難實現。

首先,讓我們建立一個應用程式,其中一個按鈕可以新增或移除一個 <p> 標籤。

示例

App.vue:

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

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

<style>
  p {
    background-color: lightgreen;
    display: inline-block;
    padding: 10px;
  }
</style>
執行示例 »

現在,讓我們將 <Transition> 元件包裹在 <p> 標籤周圍,看看我們如何為 <p> 標籤的移除新增動畫。

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

在下面的示例中,我們將使用自動可用的 v-leave-fromv-leave-to 類,在移除 <p> 標籤時建立一個淡出動畫。

示例

App.vue:

<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-leave-from {
    opacity: 1;
  }
  .v-leave-to {
    opacity: 0;
  }
  p {
    background-color: lightgreen;
    display: inline-block;
    padding: 10px;
    transition: opacity 0.5s;
  }
</style>
執行示例 »

六個 <Transition> 類

當我們使用 <Transition> 元件時,有六個類可供我們自動使用。

<Transition> 元件內的元素被新增時,我們可以使用前三個類來動畫化此過渡。

  1. v-enter-from
  2. v-enter-active
  3. v-enter-to

<Transition> 元件內的元素被移除時,我們可以使用接下來的三個類。

  1. v-leave-from
  2. v-leave-active
  3. v-leave-to

注意: <Transition> 元件的根級別只能有一個元素。

現在,讓我們使用這四個類,以便我們可以在 <p> 標籤被新增和移除時為其新增動畫。

示例

App.vue:

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

我們還可以使用 v-enter-activev-leave-active 來在元素新增時移除時設定樣式或動畫。

示例

App.vue:

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

Transition 'name' Prop

如果您有多個 <Transition> 元件,但希望其中至少一個 <Transition> 元件具有不同的動畫,則需要為 <Transition> 元件指定不同的名稱,以便區分它們。

我們可以使用 name prop 來選擇 <Transition> 元件的名稱,這也會改變過渡類的名稱,因此我們可以為該元件設定不同的 CSS 動畫規則。

<Transition name="swirl">

如果過渡 name prop 的值為 'swirl',則自動可用的類現在將以 'swirl-' 開頭,而不是 'v-'

  1. swirl-enter-from
  2. swirl-enter-active
  3. swirl-enter-to
  4. swirl-leave-from
  5. swirl-leave-active
  6. swirl-leave-to

在下面的示例中,我們使用 name prop 為 <Transition> 元件賦予不同的動畫。其中一個 <Transition> 元件沒有指定名稱,因此使用以 'v-' 開頭的自動生成的 CSS 類來設定動畫。另一個 <Transition> 元件被命名為 'swirl',以便它可以使用以 'swirl-' 開頭的自動生成的 CSS 類來設定動畫規則。

示例

App.vue:

<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>

執行示例 »

JavaScript Transition Hooks

正如剛剛提到的,每個 Transition 類都對應一個事件,我們可以透過該事件來執行一些 JavaScript 程式碼。

Transition Class JavaScript Event
v-enter-from before-enter
v-enter-active enter
v-enter-to after-enter
enter-cancelled
v-leave-from before-leave
v-leave-active leave
v-leave-to after-leave
leave-cancelled (僅 v-show)

在下面的示例中,當 after-enter 事件發生時,會執行一個方法,該方法會顯示一個紅色的 <div> 元素。

示例

App.vue:

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

您可以使用下面的示例中的“切換”按鈕來中斷 <p> 元素的 enter transition 階段,從而觸發 enter-cancelled 事件。

示例

App.vue:

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

The 'appear' Prop

如果我們有一個需要在頁面載入時進行動畫的元素,我們需要在 <Transition> 元件上使用 appear prop。

<Transition appear>
  ...
</Transition>

在此示例中,appear prop 在頁面首次載入時啟動動畫。

示例

App.vue:

<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>

執行示例 »

Transition Between Elements

只要我們透過使用 <v-if><v-else-if> 來確保一次只顯示一個元素,<Transition> 元件也可以用於在多個元素之間切換。

示例

App.vue:

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

mode="out-in"

在上一個示例中,新的影像在舊影像被移除之前就被添加了。

我們使用 <Transition> 元件上的 mode="out-in" prop 和 prop 值,以便在下一個元素被新增之前完成一個元素的移除。

示例

除了 mode="out-in" 之外,此示例還使用了計算值 'imgActive',而不是我們在上一個示例中使用的 'newImg' 方法。

App.vue:

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

Transition with Dynamic Components

我們還可以使用 <Transition> 元件來動畫化動態元件之間的切換。

示例

App.vue:

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

Vue 練習

透過練習來測試自己

練習

The <Transition> 元件會自動為我們提供 6 個不同的 CSS 類,我們可以使用它們來為元素新增動畫。

填空,使前 3 個類名按正確的順序完成,用於元素變得可見時。

  1. v-enter-
  2. v-enter-
  3. v-enter-

開始練習



×

聯絡銷售

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

報告錯誤

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

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

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