P
P
Pavel Kleshnin2019-09-20 17:04:39
Vue.js
Pavel Kleshnin, 2019-09-20 17:04:39

Why is transition-group not working?

There is a menu - it is rendered from an array of objects in $el.data
. When clicking, the isActive flag is removed from all elements, then the array is filtered (I did this on purpose, because I thought that there might be no animation during sorting), and then the deleted element with the isActive flag is inserted at the beginning array.
But the animation only works if you change the existing values ​​of the properties of this element. What could be the snag here?
I did everything as it is written in the dock (and tried to replace it with splice by index) - only one option works.

template

<template>
  <v-toolbar dense color="#195d6a">
    <transition-group name="list" tag="div" class="toolbar-wrapper">
      <p v-for='comp in links'
            :key="comp.name"
            :class="{'selected': comp.isActive}"
            @click="setActive(comp)">
            <router-link :to="comp.name" :key="comp.name">
            {{comp.text}}
            </router-link>
      </p>
    </transition-group>
  </v-toolbar>
</template>

data, methods

data() {
      return {
        links: [
          { name: '/dashboard', text: 'Панель управления', isActive: true },
          { name: '/table', text: 'Таблица', isActive: false },
          { name: '/ratesSetter', text: 'Тарифы', isActive: false },
          { name: '/chart', text: 'График', isActive: false },
          { name: '/logsBook', text: 'Журнал', isActive: false },
        ],
      }
    },
    methods: {
      setActive(comp) {
        let clicked;
        // Удаляем isActive: true у предыдущего активного элемента
        this.links = this.links.map(it => {
          return it.name === comp.name ? {...it, isActive: true} : {...it, isActive: false}
        });
        // Удаляем элемент
        this.links = this.links.filter(it => {
          if (it.name !== comp.name) {
            return true;
          } else clicked = it
        });

        // И вставляем в начало

        /* this.links.unshift(clicked) */ // Так анимация не работает
        /* this.links = [clicked, ...this.links]*/ // Так тоже

        // this.links = [                           // Не работает
        //   {
        //     ...clicked,
        //     toMakeAnimWork: Math.random()
        //   },
        //   ...this.links
        // ];

        // this.links.unshift({                    // И так ничего не работает
        //   text: clicked.text,
        //   name: clicked.name,
        //   isActive: clicked.isActive});


        //А вот так работает
        this.links.unshift({
          text: clicked.text,
          name: clicked.name + 'fff',
          isActive: clicked.isActive
        });
      },


css

.list-enter-active, .list-leave-active {
    transition: all .5s;
  }
  .list-enter, .list-leave-to {
    opacity: 0;
    transform: translateY(-50px);
  }
  .v-toolbar {
    font-family: Montserrat, Arial, sans-serif;
    font-size: 1.2rem;
  }
  .toolbar-wrapper {
    display: flex;
  }
  a {
    text-decoration: none;
    color: #95d9e5;
    transition: background-color .2s;
    padding: 13px 18px;
  }
  a:hover {
    color: #fff;
    background: #30b0c7;
  }
  p.selected a {
    color: rgba(255,255,255, .5);
  }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vladimir Sartakov, 2019-09-21
@shake_shake1

If you change :key="comp.name" to :key="comp.isActive" it will work.
Keys are used by vue to match data and dom elements from which they are generated. Therefore, the animation does not know the moment of redrawing and does not start.
You can do compound keys:
:key="comp.name + comp.isActive "

0
0xD34F, 2019-09-20
@0xD34F Vue.js

With the help of classes *-enter-active, *-leave-activeetc. removed/added elements are animated. If the key has not changed, the element will not be removed and re-added, respectively, and classes will not be added.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question