1

I've been trying to get <transition-group> to work but I just can't figure it out. Upon clicking the box, the element will change its position - which is suppose to trigger v-move class. This is the specific part of Vue documentation that I'm looking at.

Here is the link to my test app

<style>

.test-group-leave-to{
    opacity: 0;
}
.test-group-move{
    transition: transform 5s;
}

</style>

<body>

<div id='app'>
    <test-comp></test-comp>
</div>
<script>

let arrary = ['1','2','3','4','5','6','7','8','9'];

new Vue({
    el: "#app",
    components: {
        "test-comp":{
            template: `
                <div style='display:inline-block;'>
                    <transition-group name='test-group'>
                        <div 
                        class='box' 
                        v-for='(all,ind) in arr' 
                        :key='all' 
                        @click='del(ind, $event)'>{{ all }}</div>
                    </transition-group>
                </div>
            `,
            data(){
                return {
                    arr: arrary
                }
            },
            methods: {
                del(ind, e){
                    e.target.style.left = '100px';
                    this.arr.splice(ind,1);
                }
            }
        }
    }
});
</script>

tony19
  • 125,647
  • 18
  • 229
  • 307
passionateLearner
  • 722
  • 1
  • 7
  • 19
  • updated css like [this fiddle](https://www.w3schools.com/code/tryit.asp?filename=GHNLQ9BV2R36) – Sphinx Aug 11 '20 at 21:58

2 Answers2

2

A bit different approach in order to achieve smoother animations:

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Balsamiq+Sans:wght@400;700&family=Indie+Flower&family=Nunito+Sans:wght@400;600;700;800;900&display=swap" rel="stylesheet">

<style>

body{
    position: relative;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    font-family: 'Nunito', sans-serif;
}
.outer-box {
    position: relative;
    width: 100%;
    padding: 5px 10px;
    transition: all 1s;
}
.box{
    border: 1px solid blue;
    text-align: center;
    width: 50px;
    height: 50px;
    user-select: none;  
}

.animate_move-enter, .animate_move-leave-to {
  opacity: 0;
  transform: translateX(100px);
}
.animate_move-leave-active {
  position: absolute;
}

</style>
</head>
<body>

<div id='app'>
    <test-comp></test-comp>
</div>
<script>

let arrary = ['1','2','3','4','5','6','7','8','9'];

new Vue({
    el: "#app",
    components: {
        "test-comp":{
            template: `
                <div>
                    <transition-group name='animate_move'>
                      <div v-for='(all,ind) in arr' :key='all' class="outer-box">
                          <div class='box' @click='del(ind, $event)'>{{ all }}</div>
                      </div>
                    </transition-group>
                </div>
            `,
            data(){
                return {
                    arr: arrary
                }
            },
            methods: {
                del(ind, e){
                    this.arr.splice(ind,1);
                }
            }
        }
    }
});
</script>
</body>
</html>

This way you can avoid jumping blocks after they are removed.

Anwar Hossain
  • 654
  • 6
  • 21
Jakub A Suplicki
  • 4,586
  • 1
  • 23
  • 31
1

I suggest to use List Entering/Leaving Transitions instead of move transition and you should remove e.target.style.left = '100px'; :

<!DOCTYPE html>
<html>

<head>
  <title>Page Title</title>

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js"></script>
  <link href="https://fonts.googleapis.com/css2?family=Balsamiq+Sans:wght@400;700&family=Indie+Flower&family=Nunito+Sans:wght@400;600;700;800;900&display=swap" rel="stylesheet">

  <style>
    body {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      margin: 0;
      font-family: 'Nunito', sans-serif;
    }
    
    .box {
      position: relative;
      border: 1px solid blue;
      margin: 10px;
      text-align: center;
      width: 50px;
      height: 50px;
      user-select: none;
    }
    
    .test-group-enter-active,
    .test-group-leave-active {
      transition: all 1s;
    }
    
    .test-group-enter,
    .test-group-leave-to {
      opacity: 0;
      transform: translateX(100px);
    }
  </style>
</head>

<body>

  <div id='app'>
    <test-comp></test-comp>
  </div>
  <script>
    let arrary = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];

    new Vue({
      el: "#app",
      components: {
        "test-comp": {
          template: `
                <div style='display:inline-block;'>
                    <transition-group name='test-group'>
                        <div 
                        class='box' 
                        v-for='(all,ind) in arr' 
                        :key='all' 
                        @click='del(ind, $event)'>{{ all }}</div>
                    </transition-group>
                </div>
            `,
          data() {
            return {
              arr: arrary
            }
          },
          methods: {
            del(ind, e) {

              //e.target.style.left = '100px';
              this.arr.splice(ind, 1);
            }
          }
        }
      }
    });
  </script>
</body>

</html>
tony19
  • 125,647
  • 18
  • 229
  • 307
Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164