直接跳到內容

動畫技巧

Vue 提供了 <Transition><TransitionGroup> 組件來處理元素進入、離開和列表順序變化的過渡效果。但除此之外,還有許多其他製作網頁動畫的方式在 Vue 應用中也適用。這裡我們會探討一些額外的技巧。

基於 CSS class 的動畫

對於那些不是正在進入或離開 DOM 的元素,我們可以通過給它們動態添加 CSS class 來觸發動畫:

js
const disabled = ref(false)  function warnDisabled() {  disabled.value = true  setTimeout(() => {  disabled.value = false  }, 1500) }
js
export default {  data() {  return {  disabled: false  }  },  methods: {  warnDisabled() {  this.disabled = true  setTimeout(() => {  this.disabled = false  }, 1500)  }  } }
template
<div :class="{ shake: disabled }">  <button @click="warnDisabled">Click me</button>  <span v-if="disabled">This feature is disabled!</span> </div>
css
.shake {  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;  transform: translate3d(0, 0, 0); } @keyframes shake {  10%,  90% {  transform: translate3d(-1px, 0, 0);  }  20%,  80% {  transform: translate3d(2px, 0, 0);  }  30%,  50%,  70% {  transform: translate3d(-4px, 0, 0);  }  40%,  60% {  transform: translate3d(4px, 0, 0);  } }

狀態驅動的動畫

部分過渡效果可以通過動態插值來實現,例如在交互時動態地給元素綁定樣式。請看下面這個例子:

js
const x = ref(0) function onMousemove(e) {  x.value = e.clientX }
js
export default {  data() {  return {  x: 0  }  },  methods: {  onMousemove(e) {  this.x = e.clientX  }  } }
template
<div  @mousemove="onMousemove"  :style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }"  class="movearea" >  <p>Move your mouse across this div...</p>  <p>x: {{ x }}</p> </div>
css
.movearea {  transition: 0.3s background-color ease; }

Move your mouse across this div...

x: 0

除了顏色外,你還可以使用樣式綁定 CSS transform、寬度或高度。你甚至可以通過運用彈性物理模擬為 SVG 添加動畫,畢竟它們也只是元素屬性的數據綁定:

基於偵聽器的動畫

通過發揮一些創意,我們可以基於一些數字狀態,配合偵聽器給任何東西加上動畫。例如,我們可以將數字本身變成動畫:

js
import { ref, reactive, watch } from 'vue' import gsap from 'gsap' const number = ref(0) const tweened = reactive({  number: 0 }) watch(number, (n) => {  gsap.to(tweened, { duration: 0.5, number: Number(n) || 0 }) })
template
Type a number: <input v-model.number="number" /> <p>{{ tweened.number.toFixed(0) }}</p>
js
import gsap from 'gsap' export default {  data() {  return {  number: 0,  tweened: 0  }  },  watch: {  number(n) {  gsap.to(this, { duration: 0.5, tweened: Number(n) || 0 })  }  } }
template
Type a number: <input v-model.number="number" /> <p>{{ tweened.toFixed(0) }}</p>
Type a number:

0

動畫技巧已經加載完畢