Vue.js 動畫與過渡效果實戰

Amd794發表於2024-06-04

title: Vue.js 動畫與過渡效果實戰
date: 2024/6/4
updated: 2024/6/4
description:
這篇文章介紹瞭如何在網頁設計中使用過渡動畫和元件效果,以及如何利用模式和列表展示資訊。還提到了使用鉤子實現元件間通訊的方法。
categories:

  • 前端開發

tags:

  • 過渡
  • 動畫
  • 元件
  • 效果
  • 模式
  • 列表
  • 鉤子

image

第一部分:基礎知識

第1章:Vue.js 過渡系統簡介

Vue.js 提供了過渡效果的支援,使得在不同狀態之間切換時能夠以更加生動和使用者友好的方式呈現。本章將介紹 Vue.js 過渡系統的基本概念、工作原理以及如何使用過渡效果來提升使用者體驗。

1.1 Vue.js 過渡系統的基本概念

Vue.js 中的過渡效果主要透過 <transition><transition-group> 元件來實現。這些元件能夠包裹任何內容,當這些內容發生變化時,Vue.js 會自動應用過渡效果。例如,當一個元素被建立、銷燬或者更改時,Vue.js 會自動應用進入、離開或更新過渡。

1.2 過渡類名的生命週期

Vue.js 為過渡效果自動新增和移除一些類名,這些類名遵循特定的生命週期。主要包括以下幾個階段:

  • .v-enter:元素進入過渡的初始狀態。
  • .v-enter-active:元素進入過渡的啟用狀態,會應用動畫效果。
  • .v-enter-to:元素進入過渡的結束狀態,可以認為是完全進入的狀態。
  • .v-leave:元素離開過渡的初始狀態。
  • .v-leave-active:元素離開過渡的啟用狀態,會應用動畫效果。
  • .v-leave-to:元素離開過渡的結束狀態,可以認為是完全離開的狀態。
1.3 使用 <transition> 元件

<transition> 元件是 Vue.js 實現過渡效果的基礎。它可以用來包裹任何內容,當內容發生變化時,會自動應用過渡效果。使用 <transition> 元件時,需要提供 name 屬性來定義過渡的類名字首。

以下是一個簡單的例子,展示瞭如何使用 <transition> 元件來實現一個簡單的進入過渡效果:

<template>
  <transition name="fade">
    <div v-if="show">Hello, World!</div>
  </transition>
</template>

<script>
export default {
  data() {
    return {
      show: true
    };
  }
};
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 1s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

在這個例子中,當 show 變數的值為 true 時,<div> 元素會進入過渡狀態,應用 .fade-enter-active.fade-enter 類名,逐漸變得可見。當 show 變數的值為 false 時,<div> 元素會離開過渡狀態,應用 .fade-leave-active.fade-leave-to 類名,逐漸變得不可見。
歸檔 | cmdragon's Blog

第2章:CSS 過渡

2.1 CSS 過渡基礎

CSS 過渡是一種基於 CSS 實現的動畫效果,它可以在元素狀態變化時應用漸變效果。CSS 過渡通常需要設定兩個屬性:

  • transition:用於定義過渡效果的屬性和持續時間。
  • transition-property:用於定義哪些屬性需要應用過渡效果。

例如,以下是一個簡單的 CSS 過渡效果,實現了一個元素從左到右的淡入淡出效果:

.fade-in-out {
  transition: transform 1s, opacity 1s;
}

.fade-in-out.enter-active,
.fade-in-out.leave-active {
  transform: translateX(100px);
  opacity: 0;
}

.fade-in-out.enter-active {
  transform: translateX(0);
  opacity: 1;
}

.fade-in-out.leave-active {
  transform: translateX(-100px);
  opacity: 0;
}

在這個例子中,我們使用了 transition 屬性來定義需要應用過渡效果的屬性和持續時間,並使用了 transition-property 屬性來定義具體的過渡效果。

2.2 在 Vue.js 中應用 CSS 過渡

在 Vue.js 中應用 CSS 過渡非常簡單,只需要在 <transition> 元件中新增一個 css 屬性,並設定為 true 即可。這樣,Vue.js 會自動檢測元素的變化,並應用相應的過渡效果。

以下是一個簡單的例子,展示瞭如何在 Vue.js 中應用 CSS 過渡效果:

<template>
  <transition name="fade-in-out" css="true">
    <div v-if="show">Hello, World!</div>
  </transition>
</template>

<script>
export default {
  data() {
    return {
      show: true
    };
  }
};
</script>

<style>
.fade-in-out {
  transition: transform 1s, opacity 1s;
}

.fade-in-out.enter-active,
.fade-in-out.leave-active {
  transform: translateX(100px);
  opacity: 0;
}

.fade-in-out.enter-active {
  transform: translateX(0);
  opacity: 1;
}

.fade-in-out.leave-active {
  transform: translateX(-100px);
  opacity: 0;
}
</style>

在這個例子中,我們使用了 css 屬性來告訴 Vue.js 應用 CSS 過渡效果,並在 <style> 標籤中定義了具體的過渡效果。

2.3 示例:淡入淡出效果

以下是一個完整的示例,實現了一個簡單的淡入淡出效果:

<template>
  <transition name="fade-in-out" css="true">
    <div v-if="show">Hello, World!</div>
  </transition>
</template>

<script>
export default {
  data() {
    return {
      show: true
    };
  }
};
</script>

<style>
.fade-in-out {
  transition: opacity 1s;
}

.fade-in-out.enter-active,
.fade-in-out.leave-active {
  opacity: 0;
}

.fade-in-out.enter-active {
  opacity: 1;
}
</style>

在這個例子中,當 show 變數的值為 true 時,元素會淡入淡出,應用 .fade-in-out-enter-active.fade-in-out-leave-active 類名,逐漸變得可見。當 show 變數的值為 false 時,元素會淡入淡出,應用 .fade-in-out-leave-active 類名,逐漸變得不可見。

第3章:CSS 動畫

3.1 CSS 動畫基礎

CSS 動畫是透過使用 @keyframes 規則和 animation 屬性在網頁中建立動畫效果的一種方式。@keyframes 規則用於定義動畫序列,而 animation 屬性用於將動畫應用到元素上。

以下是一個簡單的 CSS 動畫示例,它將一個元素從左側移動到右側,並在這個過程中改變其顏色:

@keyframes moveAndColorChange {
  0% {
    left: 0;
    background-color: red;
  }
  100% {
    left: 100px;
    background-color: blue;
  }
}

.animated-element {
  animation: moveAndColorChange 2s linear infinite;
}

在這個例子中,moveAndColorChange 是一個動畫名稱,它定義了動畫從開始到結束的狀態變化。animation 屬性應用於 .animated-element 類,指定了動畫名稱、持續時間、運動曲線和重複次數。

3.2 在 Vue.js 中應用 CSS 動畫

在 Vue.js 中,你可以透過在元件中使用 <transition> 元件或者直接在元素上使用 @click 事件監聽器來應用 CSS 動畫。使用 <transition> 元件時,可以透過 name 屬性指定動畫對應的 CSS 類名,並透過 css 屬性告訴 Vue.js 是否使用 CSS 過渡。

以下是一個在 Vue.js 中應用 CSS 動畫的例子,它使用 <transition> 元件來實現一個點選按鈕時元素旋轉的效果:

<template>
  <div>
    <button @click="toggleRotation">Toggle Rotation</button>
    <transition name="rotate">
      <div v-if="rotate" class="rotating-element"></div>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      rotate: false
    };
  },
  methods: {
    toggleRotation() {
      this.rotate = !this.rotate;
    }
  }
};
</script>

<style>
.rotate-enter-active, .rotate-leave-active {
  animation: rotate 2s linear infinite;
}

.rotate-leave-to {
  transform: rotate(360deg);
  opacity: 0;
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.rotating-element {
  width: 100px;
  height: 100px;
  background-color: blue;
  display: inline-block;
}
</style>

在這個例子中,點選按鈕會切換 rotate 變數的值,從而使得 .rotating-element 元素進入或離開過渡狀態。rotate 類定義了動畫的關鍵幀和持續時間。rotate-enter-activerotate-leave-active 類應用於進入和離開過渡狀態的元素,而 rotate-leave-to 類定義了離開過渡的最終狀態。

3.3 示例:旋轉動畫

以下是一個完整的示例,實現了一個簡單的旋轉動畫:

<template>
  <div>
    <button @click="toggleRotation">Toggle Rotation</button>
    <transition name="rotate">
      <div v-if="rotate" class="rotating-element"></div>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      rotate: false
    };
  },
  methods: {
    toggleRotation() {
      this.rotate = !this.rotate;
    }
  }
};
</script>

<style>
.rotate-enter-active, .rotate-leave-active {
  animation: rotate 2s linear infinite;
}

.rotate-leave-to { transform: rotate(360deg); opacity: 0; }

@keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }

.rotating-element { width: 100px; height: 100px; background-color: blue; display: inline-block; }

在這個完整的示例中,我們建立了一個 Vue 元件,其中包含一個按鈕和一個正方形元素。按鈕的點選事件透過 toggleRotation 方法來切換 rotate 資料屬性的值,從而控制正方形元素的顯示與隱藏。 當正方形元素進入或離開時,<transition> 元件會應用名為 rotate 的 CSS 動畫。這個動畫透過 @keyframes 規則定義,使得元素在 2 秒內從 0 度旋轉到 360 度。rotate-enter-activerotate-leave-active 類確保動畫在元素進入和離開時都被應用。 rotate-leave-to 類定義了元素在離開過渡時的最終狀態,即旋轉 360 度並逐漸消失(透過 opacity: 0)。 這個示例展示瞭如何在 Vue.js 中結合 CSS 動畫和 Vue 的過渡系統來建立動態的使用者介面效果。透過這種方式,開發者可以輕鬆地為元件新增複雜的動畫效果,而不需要深入瞭解 JavaScript 動畫庫。

第4章:JavaScript 鉤子

在 Vue.js 中,除了使用 CSS 過渡和動畫來控制元件的過渡效果外,還可以使用 JavaScript 鉤子來實現更復雜的過渡邏輯。JavaScript 鉤子允許你在過渡的不同階段執行自定義的 JavaScript 程式碼,從而提供更多的靈活性和控制。

使用 JavaScript 鉤子控制過渡

Vue 的 <transition> 元件提供了六個 JavaScript 鉤子,可以在過渡的不同階段執行:

  1. beforeEnter(el)
  2. enter(el, done)
  3. afterEnter(el)
  4. enterCancelled(el)
  5. beforeLeave(el)
  6. leave(el, done)
  7. afterLeave(el)
  8. leaveCancelled(el)

其中,enterleave 鉤子接受第二個引數 done,這是一個回撥函式,當動畫完成時應該呼叫它。

結合 CSS 過渡與 JavaScript 鉤子

你可以結合使用 CSS 過渡和 JavaScript 鉤子來建立複雜的過渡效果。例如,你可以使用 CSS 過渡來設定初始的過渡效果,然後使用 JavaScript 鉤子來新增額外的動畫或效果。

示例:動態過渡效果

下面是一個使用 JavaScript 鉤子來控制過渡的示例:

<template>
  <button @click="show = !show">Toggle</button>
  <transition
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave"
  >
    <p v-if="show">Hello, Vue!</p>
  </transition>
</template>

<script>
export default {
  data() {
    return {
      show: false
    };
  },
  methods: {
    beforeEnter(el) {
      // 在過渡開始前設定元素的初始狀態
      el.style.opacity = 0;
    },
    enter(el, done) {
      // 在過渡期間設定元素的狀態
      Velocity(el, { opacity: 1, fontSize: '1.5em' }, { duration: 300 });
      Velocity(el, { fontSize: '1em' }, { complete: done });
    },
    leave(el, done) {
      // 在離開過渡期間設定元素的狀態
      Velocity(el, { opacity: 0, fontSize: '2em' }, { duration: 600 });
      Velocity(el, { fontSize: '1em' }, { complete: done });
    }
  }
};
</script>

在這個示例中,我們使用了 Velocity.js 動畫庫來建立更復雜的動畫效果。在 enterleave 鉤子中,我們使用 Velocity 來改變元素的 opacityfontSize。透過這種方式,我們可以建立出比純 CSS 過渡更豐富的動態效果。

透過結合 CSS 過渡和 JavaScript 鉤子,Vue.js 提供了強大的工具來建立各種複雜的過渡和動畫效果,使得使用者介面更加生動和吸引人。

第二部分:高階應用

第5章:過渡模式

在Vue.js中,過渡模式(Transition Modes)是指在元素 entering 和 leaving 時的動畫順序。Vue提供了兩種預設的過渡模式:in-outout-in

  • in-out模式:新元素先進入,然後舊元素離開。
  • out-in模式:舊元素先離開,然後新元素進入。

這兩種模式在多個元素同時進行過渡時尤其有用,比如在一個列表中新增或刪除元素時。

示例:列表項過渡

下面是一個Vue.js示例,展示瞭如何使用in-outout-in模式來處理列表項的過渡。

<template>
  <div>
    <button @click="addItem">新增專案</button>
    <button @click="removeItem">移除專案</button>
    <transition-group name="list" mode="in-out">
      <div v-for="(item, index) in items" :key="item" class="item">
        {{ item }}
      </div>
    </transition-group>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [1, 2, 3, 4, 5]
    };
  },
  methods: {
    addItem() {
      this.items.push(this.items.length + 1);
    },
    removeItem() {
      this.items.splice(0, 1);
    }
  }
};
</script>

<style>
.list-enter-active, .list-leave-active {
  transition: all 1s;
}
.list-enter-from, .list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
</style>

在這個示例中,我們有一個transition-group,它使用了in-out模式。當點選“新增專案”按鈕時,新專案會進入,而當前第一個專案會離開。當點選“移除專案”按鈕時,當前第一個專案會離開,然後新專案會進入。

<transition-group>name屬性用於定義動畫的名稱,這樣我們可以在CSS中為這個動畫定義樣式。在這個例子中,我們定義了enter-activeleave-active來指定進入和離開的過渡效果,以及enter-fromleave-to來指定進入和離開的起始狀態。

透過這種方式,我們可以控制多個元素同時過渡時的動畫順序和效果,提升使用者體驗。

第6章:動態元件與非同步元件

動態元件的過渡

在Vue中,動態元件的過渡是指當元件被動態切換時,Vue會提供平滑的過渡效果。為了實現這一點,Vue內建了<component>標籤,我們可以透過它的is屬性繫結一個動態的元件名稱。

當使用<component>標籤時,你可以使用Vue的<transition><transition-group>來包裹它,以便為動態元件提供過渡效果。

下面是一個動態元件過渡的示例:

<template>
  <div>
    <button @click="currentComponent = 'ComponentA'">切換到A</button>
    <button @click="currentComponent = 'ComponentB'">切換到B</button>
    
    <transition name="fade">
      <component :is="currentComponent"></component>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  },
  components: {
    ComponentA: {
      template: '<div>元件A</div>'
    },
    ComponentB: {
      template: '<div>元件B</div>'
    }
  }
};
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

在這個示例中,我們有兩個按鈕用於切換元件,currentComponent儲存當前活動的元件名。<transition>包裹著<component>,並定義了進入和離開的過渡效果。當點選按鈕切換元件時,Vue會提供平滑的淡入淡出效果。

非同步元件的過渡

非同步元件是指那些需要動態載入的元件,通常用於大型應用中,可以實現程式碼分割和懶載入。在使用非同步元件時,我們同樣可以為它們新增過渡效果。

下面是一個非同步元件過渡的示例:

<template>
  <div>
    <button @click="loadComponent('ComponentA')">載入元件A</button>
    <button @click="loadComponent('ComponentB')">載入元件B</button>
    
    <transition name="fade">
      <component :is="currentComponent"></component>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  },
  methods: {
    loadComponent(name) {
      this.currentComponent = name;
      // 這裡是非同步載入元件的邏輯,例如使用import()
    }
  },
  components: {
    ComponentA: {
      template: '<div>元件A</div>'
    },
    ComponentB: {
      template: '<div>元件B</div>'
    }
  }
};
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

在這個示例中,我們透過loadComponent方法動態載入元件。當點選按鈕載入新的元件時,Vue會使用定義好的過渡效果來平滑地顯示新的元件。

請注意,非同步元件的過渡效果可能不會像同步元件那樣直觀,因為非同步元件可能不會立即渲染。確保非同步元件在需要時已經載入和渲染,以便過渡效果可以正確應用。

第7章:列表過渡

使用 元件

在Vue中,<transition-group> 元件是用於渲染一個動態列表的過渡效果的。它不同於普通的 <transition> 元件,後者只能包裹單個元素,<transition-group> 則可以包裹多個元素,並且它會根據元素的新增和移除來更新它的子元素列表。

為了使用 <transition-group>,你需要在元件的 <script> 部分引入 TransitionGroup 類,並使用 components 選項註冊它。

列表項的過渡效果

<transition-group> 中,每個列表項都可以有自己的過渡效果。透過為每個列表項新增 <transition> 標籤,並設定適當的過渡屬性,你可以為列表項定義不同的動畫效果。

示例:列表排序與過濾的過渡

下面是一個使用 <transition-group><transition> 的示例,展示瞭如何在列表排序和過濾時應用過渡效果:

<template>
  <div>
    <button @click="sort('asc')">升序排序</button>
    <button @click="sort('desc')">降序排序</button>
    <button @click="filter('new')">顯示新專案</button>
    <button @click="filter('old')">顯示舊專案</button>
    
    <transition-group name="list" tag="ul">
      <li v-for="item in filteredAndSortedItems" :key="item.id">
        {{ item.text }}
      </li>
    </transition-group>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, text: '專案1', new: true },
        { id: 2, text: '專案2', new: false },
        { id: 3, text: '專案3', new: true },
        // ...更多專案
      ],
      currentSort: 'asc',
      currentFilter: 'all'
    };
  },
  computed: {
    filteredItems() {
      return this.items.filter(item => {
        return this.currentFilter === 'all' || (item.new && this.currentFilter === 'new') || (!item.new && this.currentFilter === 'old');
      });
    },
    sortedItems() {
      return [...this.filteredItems].sort((a, b) => {
        if (this.currentSort === 'asc') {
          return a.text.localeCompare(b.text);
        } else {
          return b.text.localeCompare(a.text);
        }
      });
    },
    filteredAndSortedItems() {
      return this.sortedItems;
    }
  },
  methods: {
    sort(direction) {
      this.currentSort = direction;
    },
    filter(filter) {
      this.currentFilter = filter;
    }
  }
};
</script>

<style>
.list-enter-active, .list-leave-active {
  transition: all 0.5s;
}
.list-enter-from, .list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
</style>

在這個示例中,我們有一個包含多個專案的列表。透過點選按鈕,使用者可以對列表進行排序和過濾。<transition-group> 用於包裹整個列表,而 <transition> 用於包裹每個列表項。當專案因為排序或過濾而移動位置時,<transition> 會提供平滑的過渡效果。

.list-enter-active.list-leave-active 類定義了過渡效果,list-enter-fromlist-leave-to 類定義了過渡的起始狀態和結束狀態。在這個示例中,我們設定了透明度為0和水平位移30畫素,以模擬專案離開檢視的效果。

第8章:第三方動畫庫

整合第三方動畫庫(如 Animate.css)

Animate.css 是一個預設了多種CSS動畫效果的庫,使用它可以輕鬆地為元素新增動畫效果。以下是如何在Vue專案中整合Animate.css的步驟:

  1. 安裝 Animate.css

    npm install animate.css --save
    
    
  2. 在Vue元件中引入並使用

    import 'animate.css';
    
    
  3. 在模板中應用動畫

    <template>
      <div class="animated" :class="animationType" v-if="show">Hello, World!</div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          show: false,
          animationType: 'bounce'
        };
      },
      mounted() {
        setTimeout(() => {
          this.show = true;
        }, 1000);
      }
    };
    </script>
    
    

在這個例子中,我們使用了 bounce 動畫效果。當元件掛載後,元素會在1秒後顯示,並應用 bounce 動畫。

使用 Velocity.js 進行高效能動畫

Velocity.js 是一個高效能的JavaScript動畫引擎,它與jQuery的$.animate()有著相同的API,但效能更優。以下是如何在Vue專案中使用Velocity.js的步驟:

  1. 安裝 Velocity.js

    npm install velocity-animate --save
    
    
  2. 在Vue元件中引入並使用

    import Velocity from 'velocity-animate';
    
    
  3. 在元件的方法中使用Velocity.js

    <template>
      <div ref="animatedElement">Hello, World!</div>
    </template>
    
    <script>
    import Velocity from 'velocity-animate';
    
    export default {
      methods: {
        startAnimation() {
          Velocity(this.$refs.animatedElement, { opacity: 0, translateX: '100px' }, { duration: 1000 });
        }
      },
      mounted() {
        this.startAnimation();
      }
    };
    </script>
    
    

在這個例子中,我們使用Velocity.js來動畫化一個元素的透明度和水平位移。當元件掛載後,startAnimation 方法會被呼叫,開始動畫效果。

示例:複雜動畫效果

結合Animate.css和Velocity.js,我們可以建立更復雜的動畫效果。例如,我們可以使用Animate.css來觸發一個基本的動畫,然後使用Velocity.js來新增更多的動畫細節。

<template>
  <div class="animated" :class="animationType" ref="animatedElement" v-if="show">Hello, World!</div>
</template>

<script>
import 'animate.css';
import Velocity from 'velocity-animate';

export default {
  data() {
    return {
      show: false,
      animationType: 'bounceIn'
    };
  },
  mounted() {
    setTimeout(() => {
      this.show = true;
      Velocity(this.$refs.animatedElement, { scale: 1.2 }, { duration: 500, easing: 'ease-in-out' });
    }, 1000);
  }
};
</script>

在這個例子中,我們首先使用Animate.css的 bounceIn 動畫來讓元素以彈跳的方式出現。然後,我們使用Velocity.js來增加一個縮放效果,使元素在出現後放大到1.2倍,然後恢復到原始大小。這種組合可以創造出更加豐富和複雜的動畫效果。

第三部分:實戰案例

第9章:構建動畫導航選單

設計動畫導航選單

設計動畫導航選單時,需要考慮以下幾個關鍵點:

  1. 使用者體驗:確保動畫自然、流暢,不會造成使用者操作上的困擾。
  2. 相容性:導航選單應該在各種裝置和瀏覽器上都能良好工作。
  3. 互動性:選單應該有明確的互動反饋,比如當使用者點選或懸停在選單項上時,應有相應的動畫效果。
  4. 效能:動畫效果不應過於複雜,以免影響頁面的載入速度和效能。
實現平滑的選單展開與收起

為了實現平滑的選單展開與收起效果,我們可以使用CSS3的transition屬性或者@keyframes規則,結合JavaScript來控制。以下是一個簡單的例子:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Animated Navigation Menu</title>
<style>
  /* 基本樣式 */
  nav {
    background-color: #333;
    color: white;
    padding: 10px 0;
  }
  nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
  }
  nav li {
    margin-right: 20px;
  }
  nav a {
    color: white;
    text-decoration: none;
    padding: 5px 10px;
    display: block;
    transition: background-color 0.3s ease;
  }
  nav a:hover, nav a:focus {
    background-color: #555;
  }

  /* 展開與收起的動畫 */
  @keyframes expand {
    from {
      height: 0;
    }
    to {
      height: auto;
    }
  }

  .expanded {
    animation: expand 0.5s ease forwards;
  }
</style>
</head>
<body>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Services</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>

  <script>
    // JavaScript程式碼來控制選單的展開與收起
    document.addEventListener('DOMContentLoaded', function() {
      const navLinks = document.querySelectorAll('nav ul li a');

      navLinks.forEach(link => {
        link.addEventListener('click', function(e) {
          e.preventDefault();
          const nav = this.parentElement.parentElement;
          nav.classList.toggle('expanded');
        });
      });
    });
  </script>
</body>
</html>

在這個例子中,我們定義了一個關鍵幀動畫expand,當使用者點選選單項時,選單項的父元素(nav)會切換一個expanded類,從而觸發動畫。動畫使得選單項的高度從0平滑地過渡到auto,實現了展開效果。
AD:漫畫首頁

響應式設計的考慮

在響應式設計中,導航選單應該能夠適應不同螢幕尺寸。這通常透過媒體查詢(@media)來實現。例如:

@media screen and (max-width: 768px) {
  nav ul {
    flex-direction: column;
  }
  nav li {
    margin-right: 0;
    margin-bottom: 10px;
  }
}

上述CSS規則意味著當螢幕寬度小於768畫素時,導航選單會變成垂直排列,並且每個列表項會有10畫素的垂直間距。這樣的設計可以確保使用者在小螢幕裝置上也能輕鬆地使用導航選單。

第10章:表單輸入的過渡效果

表單元素的過渡效果

在網頁設計中,表單元素的過渡效果可以提升使用者體驗,讓表單填寫過程更加流暢。過渡效果通常使用CSS的transition屬性來實現。以下是一個簡單的例子,展示瞭如何為表單元素新增過渡效果:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transitioned Form Elements</title>
<style>
  /* 基本樣式 */
  form {
    margin: 20px;
  }
  input, select, textarea {
    width: 100%;
    padding: 10px;
    margin-bottom: 10px;
    transition: border-color 0.3s;
  }
  input:focus, select:focus, textarea:focus {
    border-color: #007bff;
  }
</style>
</head>
<body>
  <form>
    <input type="text" placeholder="Name">
    <input type="email" placeholder="Email">
    <select>
      <option value="">Select a country</option>
      <option value="usa">USA</option>
      <option value="china">China</option>
    </select>
    <textarea placeholder="Message"></textarea>
    <button type="submit">Submit</button>
  </form>
</body>
</html>

在這個例子中,我們為輸入框、下拉選擇和文字域新增了transition屬性,當使用者聚焦在這些元素上時,邊框顏色會平滑地過渡到藍色,從而給使用者一個視覺上的反饋。

錯誤提示的動畫展示

錯誤提示動畫可以提高使用者填寫表單時的互動體驗,以下是一個簡單的例子,展示瞭如何使用CSS動畫來展示錯誤提示:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Error Animation</title>
<style>
  /* 基本樣式 */
  .error {
    color: red;
    display: none;
  }
  input:invalid + .error {
    display: block;
    animation: errorFadeIn 0.3s;
  }

  @keyframes errorFadeIn {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
</style>
</head>
<body>
  <form>
    <input type="text" placeholder="Name">
    <div class="error">Invalid input</div>
    <button type="submit">Submit</button>
  </form>
</body>
</html>

在這個例子中,當使用者輸入無效資料(例如,輸入的姓名不包含字母),輸入框後面的錯誤提示會透過動畫逐漸顯示出來。動畫使得錯誤提示平滑地淡入,提高了使用者體驗。

示例:互動式表單驗證

互動式表單驗證可以即時告知使用者輸入是否有效,以下是一個結合了表單過渡效果和錯誤提示動畫的完整示例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Form Validation</title>
<style>
  /* 基本樣式 */
  form {
    margin: 20px;
  }
  input, select, textarea {
    width: 100%;
    padding: 10px;
    margin-bottom: 10px;
    transition: border-color 0.3s;
  }
  input:focus, select:focus, textarea:focus {
    border-color: #007bff;
  }

  /* 錯誤提示樣式 */
  .error {
    color: red;
    display: none;
  }
  input:invalid + .error {
    display: block;
    animation: errorFadeIn 0.3s;
  }

  @keyframes errorFadeIn {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
</style>
</head>
<body>
  <form>
    <input type="text" required pattern="[A-Za-z\s]+" placeholder="Name">
    <div class="error">Please enter a valid name (only letters and spaces allowed).</div>
    <input type="email" required placeholder="Email">
    <div class="error">Please enter a valid email address.</div>
    <select required>
      <option value="">Select a country</option>
      <option value="usa">USA</option>
      <option value="china">China</option>
    </select>
    <div class="error">Please select a country.</div>
    <textarea required placeholder="Message"></textarea>
    <div class="error">Please enter a message.</div>
    <button type="submit">Submit</button>
  </form>
</body>
</html>

在這個完整的示例中,我們為每個表單元素新增了required屬性和一個pattern屬性(對於姓名輸入框),以確保使用者必須填寫這些欄位,並且輸入的資料符合特定的格式。每個輸入框後面都跟隨一個錯誤提示,當輸入無效時,這些錯誤提示會透過動畫逐漸顯示出來。

此外,我們還為表單元素新增了過渡效果,當使用者聚焦在輸入框上時,邊框顏色會平滑地過渡到藍色,提供了一個視覺上的反饋。這種結合了過渡效果和錯誤提示動畫的互動式表單驗證,不僅提高了使用者體驗,也使得表單填寫過程更加直觀和友好。

第11章:頁面載入與離開過渡

在一個單頁應用 (Single Page Application, SPA) 中,頁面的載入和離開過渡效果可以為使用者提供更好的視覺體驗。在這個示例中,我們將演示一個簡單的單頁應用,其中包含一個導航欄和兩個頁面。當使用者點選導航欄中的連結時,頁面會以動畫的形式平滑地過渡到目標頁面。
AD:專業搜尋引擎

首先,我們需要建立一個基本的 HTML 結構,包括導航欄和兩個頁面:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Page Transition Example</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header>
    <nav>
      <a href="#page-1">Page 1</a>
      <a href="#page-2">Page 2</a>
    </nav>
  </header>
  <main>
    <section id="page-1" class="page">
      <h1>Page 1</h1>
      <p>Welcome to Page 1!</p>
    </section>
    <section id="page-2" class="page">
      <h1>Page 2</h1>
      <p>Welcome to Page 2!</p>
    </section>
  </main>
  <script src="scripts.js"></script>
</body>
</html>

接下來,我們需要在 CSS 檔案中新增一些樣式和過渡效果:

/* styles.css */
body, html {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

header, main {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

nav a {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px 20px;
  border-radius: 5px;
  text-decoration: none;
  color: white;
  background-color: #333;
}

.page {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: translateX(100%);
  transition: transform 0.5s ease;
}

.page.active {
  transform: translateX(0);
}

最後,我們需要在 JavaScript 檔案中新增一些程式碼,以便在使用者點選導航欄連結時觸發頁面過渡效果:

// scripts.js
const links = document.querySelectorAll('nav a');
const pages = document.querySelectorAll('.page');

links.forEach((link, index) => {
  link.addEventListener('click', (e) => {
    e.preventDefault();

    // Remove the 'active' class from the current page
    pages.forEach((page) => {
      page.classList.remove('active');
    });

    // Add the 'active' class to the target page
    const targetPage = document.querySelector(link.getAttribute('href'));
    targetPage.classList.add('active');
  });
});

在這個示例中,我們使用了 CSS 過渡和 JavaScript 動畫來實現單頁應用的頁面載入和離開過渡效果。當使用者點選導航欄中的連結時,我們使用 JavaScript 將當前頁面的active類去除,並將目標頁面的active類新增上,從而實現了頁面之間平滑的過渡效果。

需要注意的是,由於我們在 CSS 中新增了overflow: hidden屬性,因此在頁面過渡期間,使用者將無法滾動頁面。如果你希望在頁面過渡期間保留滾動功能,可以使用其他的方法來實現頁面過渡效果。

第四部分:效能最佳化與最佳實踐

第12章:效能最佳化

在網頁開發中,效能最佳化是一個至關重要的環節,它直接關係到使用者體驗和網站的可用性。以下是關於效能最佳化的一些關鍵點和最佳實踐:

避免過度動畫

動畫可以增強使用者體驗,但過度使用動畫會導致效能問題。以下是一些避免過度動畫的建議:

  • 限制動畫數量:不要在頁面上同時執行多個複雜的動畫,這會消耗大量的CPU資源。
  • 簡化動畫:使用簡單的動畫效果,如淡入淡出、平移等,而不是複雜的3D變換或高幀率的動畫。
  • 使用CSS動畫:儘可能使用CSS動畫而不是JavaScript動畫,因為CSS動畫可以利用硬體加速,通常效能更好。
使用硬體加速

硬體加速可以顯著提高動畫和複雜視覺效果的效能。以下是如何使用硬體加速的一些方法:

  • 使用translate3dtranslateZ等3D變換:這些屬性可以觸發GPU加速,即使它們實際上並沒有進行3D變換。
  • 使用will-change屬性:這個CSS屬性可以提前告知瀏覽器哪些元素即將發生變化,從而讓瀏覽器提前準備硬體加速。
  • 避免不必要的硬體加速:雖然硬體加速可以提高效能,但過度使用也會導致記憶體消耗增加,因此應該適度使用。
效能測試與分析

效能測試和分析是最佳化效能的關鍵步驟。以下是一些常用的效能測試工具和方法:

  • Chrome DevTools:Chrome瀏覽器內建的開發者工具提供了效能分析皮膚,可以用來記錄和分析頁面載入和執行時的效能。
  • Lighthouse:這是一個由Google開發的開源自動化工具,用於改進網頁質量。它可以提供效能、可訪問性、漸進式Web應用等方面的審計報告。
  • WebPageTest:這是一個線上服務,可以測試網頁在不同瀏覽器和裝置上的效能,並提供詳細的效能報告。

在進行效能測試時,應該關注以下指標:

  • 首次內容繪製(FCP) :使用者看到頁面上的第一個內容所需的時間。
  • 首次有效繪製(FMP) :頁面主要內容載入完成的時間。
  • 總阻塞時間(TBT) :主執行緒被阻塞足夠長時間以防止輸入響應的總時間。
  • 互動時間(TTI) :頁面完全互動所需的時間。

透過這些工具和指標,開發者可以識別效能瓶頸,並採取相應的最佳化措施。效能最佳化是一個持續的過程,需要不斷地測試、分析和調整。AD:首頁 | 一個覆蓋廣泛主題工具的高效線上平臺

第13章:最佳實踐

在網頁和應用開發中,最佳實踐是確保程式碼高質量、易維護和使用者友好性的關鍵。以下是一些關於動畫的最佳實踐:

設計可維護的動畫程式碼
  • 模組化:將動畫程式碼分割成可重用的模組或元件,這樣可以在不同的場景中複用,同時降低維護成本。
  • 使用動畫庫:利用現有的動畫庫(如Animate.css、GreenSock Animation Platform(GSAP))可以簡化動畫建立過程,並保證效能。
  • 清晰命名:為動畫變數和函式使用清晰、描述性的命名,使得程式碼易於理解和維護。
  • 註釋和文件:為動畫程式碼新增註釋,說明動畫的目的和如何工作,尤其是在動畫邏輯複雜時。
  • 避免過度耦合:確保動畫程式碼與其他部分的耦合度最低,這樣修改一個部分不會影響到其他動畫。
動畫與使用者體驗
  • 目的明確:每個動畫都應該有明確的目的,比如引導使用者注意、提供反饋或改善視覺效果。
  • 適量使用:動畫可以吸引使用者注意力,但過多或過複雜的動畫可能會分散使用者注意力,影響使用者體驗。
  • 考慮效能:確保動畫在低效能裝置上也能平滑執行,避免因為動畫導致頁面卡頓。
  • 可訪問性:確保動畫不會影響螢幕閱讀器的使用,例如,透過適當的ARIA標籤為動畫新增輔助資訊。
響應式動畫設計
  • 媒體查詢:使用CSS媒體查詢根據不同裝置和螢幕尺寸調整動畫的樣式和行為。
  • 百分比和視口單位:使用百分比、vw/vh等單位建立響應式的動畫尺寸,使動畫在不同螢幕上保持一致性。
  • 動畫緩動:使用CSS的easelinearease-inease-outease-in-out等緩動函式確保動畫在不同裝置上的流暢性。
  • 效能優先:在移動裝置上,可能需要簡化或調整動畫以確保流暢的使用者體驗。

遵循這些最佳實踐可以幫助開發者建立既美觀又實用的動畫,提升使用者體驗,同時確保動畫程式碼的可維護性和效能。

附錄

A. Vue.js 過渡與動畫 API 參考

Vue.js 提供了一套強大的過渡和動畫系統,允許開發者為元件的插入、更新和移除新增動畫效果。以下是一些關鍵的 Vue.js 過渡與動畫 API:

  • <transition> 元件:用於包裹需要新增過渡效果的元素或元件。
  • <transition-group> 元件:用於列表中的多個元素或元件,支援列表的動畫過渡。
  • name 屬性:用於自定義過渡類名,例如 name="fade" 將生成 fade-enterfade-enter-active 等類名。
  • appear 屬性:設定頁面載入時是否應用過渡效果。
  • css 屬性:設定是否使用 CSS 過渡類名。
  • type 屬性:指定 Vue 如何確定過渡效果的結束時間。
  • mode 屬性:控制離開和進入動畫的先後順序。
  • enter-classleave-class 等屬性:允許自定義額外的 CSS 類名。
  • JavaScript 鉤子:提供了一系列的 JavaScript 鉤子函式,如 beforeEnterafterEnter 等,允許在動畫的不同階段執行自定義邏輯。

B. 常見問題解答

  1. 如何在 Vue.js 中新增動畫?

    • 使用 <transition><transition-group> 元件包裹需要動畫的元素,並應用相應的 CSS 類名或 JavaScript 鉤子。
  2. Vue.js 動畫不生效怎麼辦?

    • 檢查是否正確使用了 <transition><transition-group> 元件。
    • 確保 CSS 過渡或動畫類名正確應用。
    • 檢查是否有其他 CSS 規則覆蓋了過渡類名。
  3. 如何最佳化 Vue.js 動畫效能?

    • 使用硬體加速,如 translate3dtranslateZ
    • 避免在動畫中使用複雜的 CSS 屬性。
    • 使用 will-change 屬性提前通知瀏覽器元素將發生變化。

C. 資源與進一步學習

  • 官方文件Vue.js 過渡與動畫
  • 教程和課程:線上平臺如 Udemy、Coursera 提供了許多關於 Vue.js 動畫的高質量課程。
  • 社群和論壇:加入 Vue.js 社群,如 Reddit 的 Vue 子版塊、Vue.js 官方論壇,可以獲取幫助和分享經驗。
  • 部落格和文章:定期閱讀技術部落格和文章,瞭解最新的 Vue.js 動畫技術和最佳實踐。

相關文章