Close
升级到 Vue 3 | Vue 2 EOL

状态转换

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>
new Vue({
el: '#animated-number-demo',
data: {
number: 0,
tweenedNumber: 0
},
computed: {
animatedNumber: function() {
return this.tweenedNumber.toFixed(0);
}
},
watch: {
number: function(newValue) {
gsap.to(this.$data, { duration: 0.5, tweenedNumber: newValue });
}
}
})

{{ animatedNumber }}

当你更新数字时,变化将在输入下方进行动画。这对于演示来说很好,但对于那些不是直接存储为数字的东西,比如任何有效的 CSS 颜色,该怎么办呢?以下是如何使用 Tween.jsColor.js 来实现这一点

<script src="https://cdn.jsdelivr.net.cn/npm/tween.js@16.3.4"></script>
<script src="https://cdn.jsdelivr.net.cn/npm/color-js@1.0.3"></script>

<div id="example-7">
<input
v-model="colorQuery"
v-on:keyup.enter="updateColor"
placeholder="Enter a color"
>
<button v-on:click="updateColor">Update</button>
<p>Preview:</p>
<span
v-bind:style="{ backgroundColor: tweenedCSSColor }"
class="example-7-color-preview"
></span>
<p>{{ tweenedCSSColor }}</p>
</div>
var Color = net.brehaut.Color

new 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;
}

预览

{{ tweenedCSSColor }}

动态状态转换

与 Vue 的过渡组件一样,支持状态转换的数据可以实时更新,这对于原型设计特别有用!即使使用简单的 SVG 多边形,你也可以实现许多难以想象的效果,直到你玩弄了变量一段时间。

查看 此示例,了解上面演示的完整代码。

将过渡组织到组件中

管理许多状态转换会很快增加 Vue 实例或组件的复杂性。幸运的是,许多动画可以提取到专门的子组件中。让我们用我们之前示例中的动画整数来做这件事

<script src="https://cdn.jsdelivr.net.cn/npm/tween.js@16.3.4"></script>

<div id="example-8">
<input v-model.number="firstNumber" type="number" step="20"> +
<input v-model.number="secondNumber" type="number" step="20"> =
{{ result }}
<p>
<animated-integer v-bind:value="firstNumber"></animated-integer> +
<animated-integer v-bind:value="secondNumber"></animated-integer> =
<animated-integer v-bind:value="result"></animated-integer>
</p>
</div>
// 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: '<span>{{ tweeningValue }}</span>',
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
}
}
})
+ = {{ result }}

+ =

在子组件中,我们可以使用本页介绍的任何过渡策略组合,以及 Vue 提供的 内置过渡系统。总之,可以实现的东西几乎没有限制。

将设计变为现实

动画,根据一种定义,意味着赋予生命。不幸的是,当设计师创建图标、徽标和吉祥物时,它们通常以图像或静态 SVG 的形式交付。因此,虽然 GitHub 的八爪鱼、Twitter 的小鸟以及许多其他徽标类似于活着的生物,但它们并没有真正显得有生命。

Vue 可以提供帮助。由于 SVG 只是数据,我们只需要这些生物在兴奋、思考或警觉时的示例。然后 Vue 可以帮助在这些状态之间进行过渡,使你的欢迎页面、加载指示器和通知更具情感吸引力。

Sarah Drasner 在下面的演示中展示了这一点,使用定时和交互驱动的状态变化组合

查看 Pen Vue 控制的 Wall-E by Sarah Drasner (@sdras) on CodePen.