Search code examples
javascriptbuttonvuejs2vue-transitions

transition-group with v-show not working in vue2


I want to add some transition-delay effects to each element in transition-group,but something really weird happens. The first time come and leave works fine,but the second time come and leave both not working. I thought of many reasons such as key problem,transition style problem,element style problem,but all failed. Maybe settimeout function in js callback can solve it, but is there another way? I made a simple transition element as comparison,it works fine. I'll be appreciate if someone can spend time working out this issue. here are code below

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-show标签过渡实现特效单项目探究</title>
    <script src="vue.js"></script>
</head>
<body>
<div id="root">
    <button @click="isShow2=!isShow2">显示/隐藏</button>
    <transition
            name="hello"
           appear
    >
        <div class="divwidth" v-show="isShow2" :style="[{transition :'500ms'},{transitionDelay:100+'ms'}]">
            <span class="content">英语第1次考试</span>

        </div>


    </transition>
    <button @click="isShow=!isShow">显示/隐藏</button>
    <Transition-group

            name="hello"
            appear
    >
        <div class="divwidth" v-show="isShow"  key="11" :style="[{transition :'500ms'},{transitionDelay:100+'ms'}]">
            <span class="content">英语第1次考试</span>
        </div>
        <div class="divwidth" v-show="isShow"  key="12" :style="[{transition :'300ms'},{transitionDelay:100+'ms'}]">
            <span class="content">英语第2次考试</span>
        </div>
    </Transition-group>


</div>
</body>
<script>
    new Vue({
        el: "#root",
        data() {
            return {
                isShow: true,
                isShow2: true
            }
        },
    })
</script>
<style>
    .divwidth {
        width: 60%;
        margin-top: 15px;
    }

    .content {
        /*background-image: linear-gradient(red, yellow, blue);用于创建一个线性渐变的" 图像 "*/
        background-color: orange;
        width: auto;
        /*margin: 20px;*/
        /*margin-top: 0px;*/
        /*padding-top: 10px;*/
        padding: 6px;
        font-size: 20px;
        border: 10px;
        border-radius: 8px;
        /*line-height: 30px;*/

    }

    /*.hello-enter-active, .hello-leave-active  {*/
    /*    transition: 300ms linear;*/
    /*    !*transition-delay:200ms*!*/
    /*}*/

    .hello-enter, .hello-leave-to {
        opacity: 0;
        transform: translateX(50%);
    }


 /*.hello-move { transition: all 0.6s ease; }*/
/*.hello-leave-active{*/
/*    position: absolute; */
/*}*/

</style>
</html>

I tried v-if,it works fine,but I don't want to get rid of elements from DOM . as to v-show I thought of many reasons such as key problem,transition style problem,element style problem,but all failed. I expect to see transition effects happens every time i click the button,but in my example ,effects failed at second time come and leave.


Solution


  • for me the is working:

    vue docomotion

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8" />
        <title>v-show标签过渡实现特效单项目探究</title>
    </head>
    
    <body>
        <div id="root">
            <button @click="isShow2=!isShow2">显示/隐藏</button>
            <transition name="hello" appear>
                <div class="divwidth" v-show="isShow2" :style="[{transition :'500ms'},{transitionDelay:100+'ms'}]">
                    <span class="content">英语第1次考试</span>
                </div>
            </transition>
            <button @click="isShow=!isShow">显示/隐藏</button>
            <transition v-for="(btn,index) in btns" :key="index" name="hello" appear>
                <div class="divwidth" v-show="isShow" :style="[{transition :btn.transition},{transitionDelay:100+'ms'}]">
                    <span class="content">{{btn.text}}</span>
                </div>
            </transition>
        </div>
        <script type="module">
            import Vue from "https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.esm.browser.js"
            console.log(Vue)
            const vue = new Vue({
                el: "#root",
                data() {
                    return {
                        isShow: true,
                        isShow2: true,
                        btns: [
                            { text: "英语第1次考试", transition: "500ms" },
                            { text: "英语第2次考试", transition: "500ms" }
                        ],
                    }
                },
            })
        </script>
    </body>
    
    <style>
        .divwidth {
            width: 60%;
            margin-top: 15px;
        }
    
        .content {
            /*background-image: linear-gradient(red, yellow, blue);用于创建一个线性渐变的" 图像 "*/
            background-color: orange;
            width: auto;
            /*margin: 20px;*/
            /*margin-top: 0px;*/
            /*padding-top: 10px;*/
            padding: 6px;
            font-size: 20px;
            border: 10px;
            border-radius: 8px;
            /*line-height: 30px;*/
        }
    
        /*.hello-enter-active, .hello-leave-active  {*/
        /*    transition: 300ms linear;*/
        /*    !*transition-delay:200ms*!*/
        /*}*/
    
        .hello-enter,
        .hello-leave-to {
            opacity: 0;
            transform: translateX(50%);
        }
    
        /*.hello-move { transition: all 0.6s ease; }*/
        /*.hello-leave-active{*/
        /*    position: absolute; */
        /*}*/
    </style>
    
    </html>