Vue.js 状态过渡
Vue 的過渡系統提供了非常多簡單的方法設置進入、離開和列表的動效。那么對于數據元素本身的動效呢,比如:
- 數字和運算
- 顏色的顯示
- SVG 節點的位置
- 元素的大小和其他的屬性
所有的原始數字都被事先存儲起來,可以直接轉換到數字。做到這一步,我們就可以結合 Vue 的響應式和組件系統,使用第三方庫來實現切換元素的過渡狀態。
狀態動畫與偵聽器
通過偵聽器我們能監聽到任何數值屬性的數值更新。可能聽起來很抽象,所以讓我們先來看看使用?GreenSock?一個例子:
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.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) {TweenLite.to(this.$data, 0.5, { tweenedNumber: newValue });}} }) |
?
0
當你把數值更新時,就會觸發動畫。這個是一個不錯的演示,但是對于不能直接像數字一樣存儲的值,比如 CSS 中的 color 的值,通過下面的例子我們來通過?Tween.js?和?Color.js?實現一個例子:
| <script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script> <script src="https://cdn.jsdelivr.net/npm/color-js@1.0.3"></script><div id="example-7"><inputv-model="colorQuery"v-on:keyup.enter="updateColor"placeholder="Enter a color"><button v-on:click="updateColor">Update</button><p>Preview:</p><spanv-bind:style="{ backgroundColor: tweenedCSSColor }"class="example-7-color-preview"></span><p>{{ tweenedCSSColor }}</p> </div> |
| 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; } |
?Update
Preview:
#000000
動態狀態過渡
就像 Vue 的過渡組件一樣,數據背后狀態過渡會實時更新,這對于原型設計十分有用。當你修改一些變量,即使是一個簡單的 SVG 多邊形也可實現很多難以想象的效果。
Sides: 10Minimum Radius: 50%Update Interval: 500 milliseconds
上述 demo 背后的代碼可以通過這個 fiddle?進行詳閱。
把過渡放到組件里
管理太多的狀態過渡會很快的增加 Vue 實例或者組件的復雜性,幸好很多的動畫可以提取到專用的子組件。
我們來將之前的示例改寫一下:
| <script src="https://cdn.jsdelivr.net/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> |
| // 這種復雜的補間動畫邏輯可以被復用 // 任何整數都可以執行動畫 // 組件化使我們的界面十分清晰 // 可以支持更多更復雜的動態過渡 // 策略。 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 = thisfunction animate () {if (TWEEN.update()) {requestAnimationFrame(animate)}}new TWEEN.Tween({ tweeningValue: startValue }).to({ tweeningValue: endValue }, 500).onUpdate(function (object) {vm.tweeningValue = object.tweeningValue.toFixed(0)}).start()animate()}} })// 所有的復雜度都已經從 Vue 的主實例中移除! new Vue({el: '#example-8',data: {firstNumber: 20,secondNumber: 40},computed: {result: function () {return this.firstNumber + this.secondNumber}} }) |
?+??= 60
20?+?40?=?60
我們能在組件中結合使用這一節講到各種過渡策略和 Vue?內建的過渡系統。總之,對于完成各種過渡動效幾乎沒有阻礙。
賦予設計以生命
只要一個動畫,就可以帶來生命。不幸的是,當設計師創建圖標、logo 和吉祥物的時候,他們交付的通常都是圖片或靜態的 SVG。所以,雖然 GitHub 的章魚貓、Twitter 的小鳥以及其它許多 logo 類似于生靈,它們看上去實際上并不是活著的。
Vue 可以幫到你。因為 SVG 的本質是數據,我們只需要這些動物興奮、思考或警戒的樣例。然后 Vue 就可以輔助完成這幾種狀態之間的過渡動畫,來制作你的歡迎頁面、加載指示、以及更加帶有情感的提示。
Sarah Drasner 展示了下面這個 demo,這個 demo 結合了時間和交互相關的狀態改變:
?
from:?https://cn.vuejs.org/v2/guide/transitioning-state.html
總結
以上是生活随笔為你收集整理的Vue.js 状态过渡的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue.js 进入/离开 列表过渡
- 下一篇: Vue.js 自定义指令