Заавар
Үндсэн ойлголт
- Суулгах заавар
- Танилцуулга
- Vue-ийн Instance үүсгэх
- Template Syntax
- Computed Properties and Watchers
- Class болон Style Bindings
- Conditional Rendering
- Жагсаалт рэндэрлэх
- Event Handling
- Form Input холболтууд
- Component-уудын үндэс
Components In-Depth
- Component Registration
- Props
- Custom Events
- Slots гэж юу вэ
- Динамик & Асинхрон компонентууд
- Handling Edge Cases
Транситион & Анимэйшн
- Enter/Leave & List Transitions
- State Transitions
Дахин ашиглагдах & Зохиомж
- Mixins
- Custom Directives
- Рэндэр функцууд & JSX
- Нэмэлтүүд
- Filter-үүд
Багаж хэрэгсэл
- Single File Components
- Unit тэст
- TypeScript дэмжлэг
- Production Deployment
Өргөтгөх
- Routing - Чиглүүлэлт
- State Management
- Server-Side Rendering
- Security
Шинж чанар
- Reactivity in Depth
Шинэ хувилбарлуу шилжих
- Vue 1.x ээс шилжих
- Vue Router 0.7.x оос шилжих
- Vuex 0.6.x аас 1.0 руу шилжих
Мета
- Бусад фрэймворктой харьцуулбал
- Vue.js Community-д нэгдэх!
- Багийн гишүүдийн танилцуулга
State Transitions
Vue’s transition system offers many simple ways to animate entering, leaving, and lists, but what about animating your data itself? For example:
- numbers and calculations
- colors displayed
- the positions of SVG nodes
- the sizes and other properties of elements
All of these are either already stored as raw numbers or can be converted into numbers. Once we do that, we can animate these state changes using 3rd-party libraries to tween state, in combination with Vue’s reactivity and component systems.
Animating State with Watchers
Watchers allow us to animate changes of any numerical property into another property. That may sound complicated in the abstract, so let’s dive into an example using 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 });
}
}
})
{{ animatedNumber }}
When you update the number, the change is animated below the input. This makes for a nice demo, but what about something that isn’t directly stored as a number, like any valid CSS color for example? Here’s how we could accomplish this with Tween.js and 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">
<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;
}
Preview:
{{ tweenedCSSColor }}
Dynamic State Transitions
As with Vue’s transition components, the data backing state transitions can be updated in real time, which is especially useful for prototyping! Even using a simple SVG polygon, you can achieve many effects that would be difficult to conceive of until you’ve played with the variables a little.
See this fiddle for the complete code behind the above demo.
Organizing Transitions into Components
Managing many state transitions can quickly increase the complexity of a Vue instance or component. Fortunately, many animations can be extracted out into dedicated child components. Let’s do this with the animated integer from our earlier example:
<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>
// 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
}
}
})
Within child components, we can use any combination of transition strategies that have been covered on this page, along with those offered by Vue’s built-in transition system. Together, there are very few limits to what can be accomplished.
Bringing Designs to Life
To animate, by one definition, means to bring to life. Unfortunately, when designers create icons, logos, and mascots, they’re usually delivered as images or static SVGs. So although GitHub’s octocat, Twitter’s bird, and many other logos resemble living creatures, they don’t really seem alive.
Vue can help. Since SVGs are just data, we only need examples of what these creatures look like when excited, thinking, or alarmed. Then Vue can help transition between these states, making your welcome pages, loading indicators, and notifications more emotionally compelling.
Sarah Drasner demonstrates this in the demo below, using a combination of timed and interactivity-driven state changes:
See the Pen Vue-controlled Wall-E by Sarah Drasner (@sdras) on CodePen.