Vue 的过渡系统提供了非常多简单的方法设置进入、离开和列表的动画效果。
那么对于数据元素本身的动效呢,比如:
这些数据要么本身就以数值形式存储,要么可以转换为数值。有了这些数值后,我们就可以结合 Vue 的响应性和组件系统,使用第三方库来实现切换元素的过渡状态。
通过侦听器我们能监听到任何数值类属性的数值变化。
让我们先来看看使用 GreenSock 的例子:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script> <div id="animated-number-demo"> <input v-model.number="number" type="number" step="20" /> <p>{{ animatedNumber }}</p> </div>
const Demo = { data() { return { number: 0, tweenedNumber: 0 } }, computed: { animatedNumber() { return this.tweenedNumber.toFixed(0) } }, watch: { number(newValue) { gsap.to(this.$data, { duration: 0.5, tweenedNumber: newValue }) } } } Vue.createApp(Demo).mount('#animated-number-demo')
更新数字时,输入框下方的展示数字会有炫酷的动画效果。
编写太多的状态过渡会快速增加组件实例的复杂度。
幸好很多的动画可以提取到专用的子组件中,我们把之前的示例改写一下:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script> <div id="app"> <input v-model.number="firstNumber" type="number" step="20" /> + <input v-model.number="secondNumber" type="number" step="20" /> = {{ result }} <p> <animated-integer :value="firstNumber"></animated-integer> + <animated-integer :value="secondNumber"></animated-integer> = <animated-integer :value="result"></animated-integer> </p> </div>
const app = Vue.createApp({ data() { return { firstNumber: 20, secondNumber: 40 } }, computed: { result() { return this.firstNumber + this.secondNumber } } }) app.component('animated-integer', { template: '<span>{{ fullValue }}</span>', props: { value: { type: Number, required: true } }, data() { return { tweeningValue: 0 } }, computed: { fullValue() { return Math.floor(this.tweeningValue) } }, methods: { tween(newValue, oldValue) { gsap.to(this.$data, { duration: 0.5, tweeningValue: newValue, ease: 'sine' }) } }, watch: { value(newValue, oldValue) { this.tween(newValue, oldValue) } }, mounted() { this.tween(this.value, 0) } }) app.mount('#app')