Vue.js - это простой в использовании фреймворк для веб-приложений, который мы можем использовать для разработки интерактивных интерфейсных приложений.

В этой статье мы рассмотрим, как добавлять переходы при отображении списков.

Список переходов

Если мы хотим применить переходы для одновременного рендеринга нескольких элементов с v-for, мы можем использовать компонент transition-group.

В отличие от transition, по умолчанию он отображает span. Мы можем изменить отображаемый элемент с помощью атрибута tag.

Режимы перехода недоступны, потому что мы не чередуем взаимоисключающие элементы.

Элементы внутри всегда должны иметь уникальный атрибут key.

Классы перехода CSS будут применяться к внутренним элементам, а не к самой группе или контейнеру.

Список переходов входа / выхода

Например, мы можем добавить переход при добавлении или удалении элемента из списка следующим образом:

src/index.js :

new Vue({
  el: "#app",
  data: {
    items: [1, 2, 3],
    nextNum: 4
  },
  methods: {
    add() {
      this.items.push(this.nextNum++);
    },
    remove() {
      this.items.pop();
    }
  }
});

src/style.css :

.list-enter-active,
.list-leave-active {
  transition: all 1s;
}
.list-enter,
.list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <link
      rel="stylesheet"
      type="text/css"
      href="./src/styles.css"
      media="screen"
    />
  </head>
  <body>
    <div id="app">
      <button @click="add">Add</button>
      <button @click="remove">Remove</button>
      <transition-group name="list" tag="p">
        <span v-for="item in items" :key="item">
          {{ item }}
        </span>
      </transition-group>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

Затем, когда мы нажимаем кнопку «Добавить», мы видим число, добавленное в конец списка. Когда мы нажимаем «Удалить», крайнее правое число удаляется.

Как и transition, мы определили классы с префиксом name, который мы указали.

Кроме того, мы указали имя tag, чтобы у нас был элемент span, отображаемый для каждого элемента в элементе p.

Список переходов перемещения

transition-group может анимировать смену позиции, кроме того, входить и выходить. Мы можем сделать это, добавив класс v-move.

Как и другие классы, мы добавляем к нему префикс атрибута name, и мы также можем вручную указать класс с атрибутом move-class.

Например, мы можем добавить эффект, когда мы перемешиваем позиции чисел следующим образом:

src/index.js :

new Vue({
  el: "#app",
  data: {
    items: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  },
  methods: {
    shuffle() {
      this.items = _.shuffle(this.items);
    }
  }
});

src/styles.css :

.flip-list-move {
  transition: transform 1s;
}

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
    <link rel="stylesheet" type="text/css" href="./src/styles.css" />
  </head>
  <body>
    <div id="app">
      <button @click="shuffle">Shuffle</button>
      <transition-group name="flip-list" tag="div">
        <div v-for="item in items" :key="item">
          {{ item }}
        </div>
      </transition-group>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

Когда мы нажимаем «Перемешать», мы видим, что перемешивание немного растягивается во времени.

Vue использует FLIP для плавного перехода между элементами из старого положения в новое.

Они не работают с элементами, установленными на display: inline, мы должны использовать display: inline-block или размещать элементы в контейнере flexbox.

Потрясающие переходы в списке

Мы можем расположить переходы по списку следующим образом:

src/index.js :

new Vue({
  el: "#app",
  data: {
    items: ["foo", "bar", "baz"],
    query: ""
  },
  computed: {
    filteredItems() {
      if (!this.query) {
        return this.items;
      }
      return this.items.filter(i => i === this.query);
    }
  },
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0;
      el.style.height = 0;
    },
    enter(el, done) {
      var delay = el.dataset.index * 150;
      setTimeout(() => {
        Velocity(el, { opacity: 1, height: "1.6em" }, { complete: done });
      }, delay);
    },
    leave(el, done) {
      var delay = el.dataset.index * 150;
      setTimeout(() => {
        Velocity(el, { opacity: 0, height: 0 }, { complete: done });
      }, delay);
    }
  }
});

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
  </head>
  <body>
    <div id="app">
      <input v-model="query" />
      <transition-group
        name="flip-list"
        tag="div"
        v-bind:css="false"
        v-on:before-enter="beforeEnter"
        v-on:enter="enter"
        v-on:leave="leave"
      >
        <div v-for="item in filteredItems" :key="item">
          {{ item }}
        </div>
      </transition-group>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

Мы видим, что теперь у нас есть переходы при фильтрации списка.

Заключение

Мы можем создавать переходы при рендеринге списка с v-for, как мы делаем с v-if.

Разница в том, что мы должны указать имя тега контейнера, если мы не хотим отображать диапазон.

Кроме того, мы всегда должны добавлять атрибут key к каждому элементу внутри.

Мы можем иметь переходы при изменении положения элемента, указав стиль CSS для класса v-move, который можно переименовать, если мы укажем префикс или имя класса.

Указание переходов входа и выхода или v-for аналогично указанию переходов входа и выхода для v-if.

Наконец, мы можем создавать переходы с помощью JavaScript с помощью Velocity.js, как v-if анимацию.