Vue uses javascript hook function to realize invalid animation

wants to encapsulate a simple animation component, which is implemented with css, and the effect is feasible, as follows:

<template>
    <div>
        <transition name="bar">
            <slot></slot>
        </transition>
    </div>
</template>

<style lang="stylus" scoped>
.bar-enter-active, .bar-leave-active{
    transition: all .3s;
}

.bar-leave-active{
    transform translateY(200px)
}

.bar-enter{
    transform translateY(200px)
}
</style>

because a lot of dynamic calculations are needed, I want to change the javascript hook function to implement it, but I find that no matter how I try it, it doesn"t work.

<template>
    <div>
        <transition
            v-on:before-enter="beforeEnter"
            v-on:enter="enter"
            v-on:leave="leave"
        >
            <slot></slot>
        </transition>
    </div>
</template>
<script>
export default {
    name: "animation",
    methods: {
        beforeEnter: function (el) {
            el.style.transform = "translate-y(200px)"
        },
        // 
        //  CSS 
        enter: function (el, done) {
            el.style.transitionDuration = "3s"
            el.style.transitionProperty = "all"
            done()
        },

        // 
        //  CSS 
        leave: function (el, done) {
            el.style.transform = "translate-y(200px)"
            // el.style.transition = "all 3s"
            el.style.transitionDuration  = "3s"
            el.style.transitionProperty = "all"
            done()
        },
    }
}
</script>

what is the problem?

Apr.03,2021

the subject may not quite understand the use of javascript hook animation.
your first kind is to use the class class name to switch the transition animation realized through css3 itself, but the hook function to achieve animation is another concept, which needs to be realized by yourself with a timer, of course, it can also be used with css. There is an official explanation for this. The following is a simple description of an opacity transition demo,
subject that you can refer to and understand. If in doubt, welcome to discuss it again.

<template>
    <transition
        v-on:before-enter="beforeEnter"
        v-on:enter="enter"
        v-on:leave="leave"
    >
        <slot></slot>
    </transition>
</template>
<script>
export default {
    name: 'animation',
    data() {
        return {
            enterTimer: null,
            leaveTimer: null
        }
    },
    methods: {
        beforeEnter: function(el) {
            el.style.opacity = 0
            el.style.transform = 'translateX(0px)'
            el.style.transformOrigin = 'left'
        },
        // 
        //  CSS 
        enter: function(el, done) {
            clearInterval(this.leaveTimer)
            let _v = 0
            this.enterTimer = setInterval(() => {
                if (_v < 1) {
                    _v += 0.01
                } else {
                    _v = 1
                    clearInterval(this.enterTimer)
                    done()
                }
                el.style.opacity = _v
                el.style.transform = `translateX(${_v * 100}px)`
            }, 30)
        },

        // 
        //  CSS 
        leave: function(el, done) {
            clearInterval(this.enterTimer)
            let _v = 1
            this.leaveTimer = setInterval(() => {
                if (_v > 0) {
                    _v -= 0.01
                } else {
                    _v = 0
                    clearInterval(this.leaveTimer)
                    done()
                }
                el.style.opacity = _v
                el.style.transform = `translateX(${_v * 100}px)`
            }, 30)
        }
    }
}
</script>

enter: function (el, done) {
   this.$nextTick(()=>{
            el.style.transitionDuration = "3s"
            el.style.transitionProperty = "all"
            })
            done()
        },

try this


@ donglegend Hello, thank you, basically, but it feels flawed in this way, as follows:

/ / suppose I want to complete the animation in 1s (slide 250px)
/ / then how many times do I need the function to execute?
/ / obviously, if I want the animation to look smoother, the smaller the pixels I have to move each time, so the more frequently the function is executed;
/ / on the contrary, if the interval between functions is larger, the animation will be very ugly (too many pixels at a time)

question: assuming that my sliding distance is large enough (1000px), the execution time is short enough (0.3s), and the animation looks smooth enough (each time I move 5px), how long does it take for the function to execute? . 1000 / (0 / 5), 0.3s need to execute the function 200 times, once every 0.0015s. Is there a problem with executing the function so frequently? What if you can only move 1px at a time?

in addition, these calculations are troublesome, which is not as convenient as css3 animation.

the animation I realized with css is compared with that achieved by js hook, both 0.3s. I always feel that the animation of css should be fast and smooth.

<template>
    <transition
        v-on:before-enter="beforeEnter"
        v-on:enter="enter"
        v-on:leave="leave"
    >
        <slot></slot>
    </transition>
</template>
<script>
export default {
    name: 'animation',
    data() {
        return {
            enterTimer: null,
            leaveTimer: null
        }
    },
    methods: {
        beforeEnter: function(el) {
            //
            el.style.bottom = '-250px'
        },
        enter: function(el, done) {
            clearInterval(this.leaveTimer)
            let _v = 0
            //1s250px
            //
            //;
            //
            this.enterTimer = setInterval(() => {
                if (_v < 250) {
                    _v += 2.5
                } else {
                    _v = 250
                    clearInterval(this.enterTimer)
                    done()
                }
                el.style.opacity = _v
                el.style.transform = `translateY(-${_v}px)`
            }, 3)
        },
        leave: function(el, done) {
            clearInterval(this.enterTimer)
            let _v = 250
            this.leaveTimer = setInterval(() => {
                if (_v > 0) {
                    _v -= 2.5
                } else {
                    _v = 0
                    clearInterval(this.leaveTimer)
                    done()
                }
                el.style.opacity = _v
                el.style.transform = `translateY(-${_v}px)`
            }, 3)
        }
    }
}
</script>

has always thought that the official price shows that the two methods are equivalent, and the corresponding demo of the two methods are not equivalent, which feels like a huge pit

.
Menu