![9e07c1c7d877eb51d238e631bf7a81bf.png](https://i-blog.csdnimg.cn/blog_migrate/86d3c0d609fda8b988a461e98c40df55.jpeg)
Vue的过渡系统提供了许多简单的方法来动画进入,离开和列表,但动画数据本身又如何呢?例如:
- 数字和计算
- 显示颜色
- SVG节点的位置
- 元素的大小和其他属性
所有这些都已经存储为原始数字或可以转换为数字。一旦我们这样做了,我们就可以使用第三方库对这些状态更改进行动画处理,以结合Vue的反应性和组件系统。
用观察者动画状态
观察者允许我们将任何数值属性的变化动画成另一个属性。这听起来可能听起来很复杂,所以我们来深入一个使用Tween.js的例子:
{{ animatedNumber }}
new Vue({ el: '#animated-number-demo', data: { number: 0, animatedNumber: 0 }, watch: { number: function(newValue, oldValue) { var vm = this function animate () { if (TWEEN.update()) { requestAnimationFrame(animate) } } new TWEEN.Tween({ tweeningNumber: oldValue }) .easing(TWEEN.Easing.Quadratic.Out) .to({ tweeningNumber: newValue }, 500) .onUpdate(function () { vm.animatedNumber = this.tweeningNumber.toFixed(0) }) .start() animate() } }})
当您更新号码时,更改会在输入下面显示动画。这使得一个很好的演示,但什么东西不是直接存储为一个数字,如任何有效的CSS颜色,例如?以下是我们如何通过添加Color.js来实现这一点:
Update
Preview:
{{ tweenedCSSColor }}
var Color = net.brehaut.Colornew Vue({ el: '#example-7', data: { colorQuery: '', color: { red: 0, green: 0, blue: 0, alpha: 1 }, tweenedColor: {} }, created: function () { this.tweenedColor = Object.assign({}, this.color) }, watch: { color: function () { function animate () { if (TWEEN.update()) { requestAnimationFrame(animate) } } new TWEEN.Tween(this.tweenedColor) .to(this.color, 750) .start() animate() } }, computed: { tweenedCSSColor: function () { return new Color({ red: this.tweenedColor.red, green: this.tweenedColor.green, blue: this.tweenedColor.blue, alpha: this.tweenedColor.alpha }).toCSS() } }, methods: { updateColor: function () { this.color = new Color(this.colorQuery).toRGB() this.colorQuery = '' } }}).example-7-color-preview { display: inline-block; width: 50px; height: 50px;}
动态状态转换
与Vue的转换组件一样,数据支持状态转换可以实时更新,这对原型设计特别有用!即使使用简单的SVG多边形,也可以实现许多难以想象的效果,直到您稍稍使用变量。
请参阅此fiddle以获取上述演示背后的完整代码。
将转换组织成组件
管理许多状态转换可能会快速增加Vue实例或组件的复杂性。幸运的是,许多动画可以提取出专用的子组件。我们用前面例子的动画整数来做这件事:
+ = {{ result }}
+ =
// This complex tweening logic can now be reused between// any integers we may wish to animate in our application.// Components also offer a clean interface for configuring// more dynamic transitions and complex transition// strategies.Vue.component('animated-integer', { template: '{{ tweeningValue }}', props: { value: { type: Number, required: true } }, data: function () { return { tweeningValue: 0 } }, watch: { value: function (newValue, oldValue) { this.tween(oldValue, newValue) } }, mounted: function () { this.tween(0, this.value) }, methods: { tween: function (startValue, endValue) { var vm = this function animate () { if (TWEEN.update()) { requestAnimationFrame(animate) } } new TWEEN.Tween({ tweeningValue: startValue }) .to({ tweeningValue: endValue }, 500) .onUpdate(function () { vm.tweeningValue = this.tweeningValue.toFixed(0) }) .start() animate() } }})// All complexity has now been removed from the main Vue instance!new Vue({ el: '#example-8', data: { firstNumber: 20, secondNumber: 40 }, computed: { result: function () { return this.firstNumber + this.secondNumber } }})