vue的动画应用

动画可以使用css动画,也可以用钩子加载js动画

css动画有个缺点,如果某些动画效果的值需要动态去改变,那只能使用js动画

如果是多个dom都要连着动画怎么办呢
比如需求是一个进度条+小火箭,进度条需要动态的属性是width,小火箭需要动态的属性是margin-left

那么可以使用transition标签,也可以使用transition-group标签

使用transition标签,思路是取其中一个dom作为基准,执行js动画,其他dom在基准dom的时间线回调里做属性值的变化,当然,相对于使用transition-group标签,同步的时候那些边界值可能要维护得更多。

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<div ref="progressRed" class="head-panel-progress-red" v-if="show" :style="{'width': `${marginLeftRocket}`}"  ></div>
<transition v-on:enter="enter"
v-on:before-enter="beforeEnter"
v-on:after-enter="afterEnter"
v-on:before-leave="beforeLeave"
:css="false"
name="animate"
mode="in-out">
<img class="head-panel-progress-rocket" src="https://qiniu-koala.kaolalicai.cn/app/cash_flow_record/img_progress_rocket.png" v-if="show" :class="flagClassRocket">
</transition>


beforeEnter(el) {
el.style.marginLeft = '0%'
},
enter(el, done) {
Velocity(el, {
marginLeft: `${this.beatPercent}%`
}, {
duration: 1000,
progress: () => {
this.marginLeftRocket = el.style.marginLeft
},
complete: () => {
done()
}
})
},
afterEnter(el) {
this.marginLeftRocket = el.style.marginLeft
},
beforeLeave() {
this.marginLeftRocket = '0%'
},

使用transition-group标签,比较简单,n个dom同时执行,动态改变属性值,由系统去维护时间线,完美,可能也有缺点,group的子dom需要统一的标签(这点没验证)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<transition-group v-on:enter="enter"
v-on:before-enter="beforeEnter"
v-on:after-enter="afterEnter"
v-on:before-leave="beforeLeave"
:css="false"
tag="div"
name="animate"
mode="in-out">
<div :key="'progressRed'"
:data-name="'red'"
class="head-panel-progress-red"
v-if="show" ></div>
<div :key="'progressRocket'"
:data-name="'rocket'"
class="head-panel-progress-rocket"
v-if="show"></div>
</transition-group>

enter(el, done) {
let properties = el.dataset.name === 'rocket' ? { marginLeft: `${this.beatPercent}%` } : { width: `${this.beatPercent}%` }
Velocity(el, properties, {
duration: 1000,
complete: () => {
done()
}
})
},