Vue.js Transitions - вход и выход, в зависимости от увеличения / уменьшения значения

В настоящее время у меня есть следующий компонент блока перехода:

<div
   v-if="!surveyResultIsReady"
   class="vh-md-40 position-relative"
   >
   <transition
      name="custom-classes-transition"
      enter-active-class="animated slideInRight"
      leave-active-class="animated slideOutLeft"
      >
      <div
         v-bind:key="step"
         class="w-100 position-absolute mx-auto"
         >
         <SurveyActiveQuestion
            v-if="!surveyResultIsReady"
            v-bind:question="activeQuestion()"
            v-bind:totalQuestions="totalQuestions"
            v-on:activeQuestionAnswered="activeQuestionAnswered()"
            />
      </div>
   </transition>
</div>

Переход регулируется this.step ценность (v-bind:key="step").

Переход отлично смотрится, когда this.step++, переход выполняется в "правильном" направлении: слева направо. Однако когдаthis.step-- переход такой же.

Мне было интересно, как мне исправить это, чтобы смахнуть назад справа налево для this.step-- направление?

2 ответа

Решение

Для перехода вам нужны два разных состояния ввода CSS, потому что вы хотите скользить в обоих направлениях. Использование привязки дляenter-class (не то же самое, что enter-active-class), вы можете выделить положение слайда в 2 отдельных класса ввода CSS и поменять их местами в зависимости от изменения в step. Например, вот новая привязка:

:enter-class="enterClass"

enterClass - это свойство данных, установленное для строки имени класса с увеличением или уменьшением с использованием watch на step:

watch: {
  step(old, value) {
    this.enterClass = value > old ? 'slide-in-right' : 'slide-in-left'; 
  }
}

А вот классы:

.animated {
  transition: transform .5s;
}
.slide-in-left {
  transform: translate(-100%, 0);
}
.slide-in-right {
  transform: translate(100%, 0);
}

ДЕМО Собирая все вместе, вот упрощенная версия вашего кода:

new Vue({
  el: "#app",
  data() {
    return {
      step: 1,
      enterClass: ''
    }
  },
  watch: {
    step(value, old) {
      this.enterClass = value > old ? 'slide-in-left' : 'slide-in-right'; 
    }
  }
});
[v-cloak] {
  display:none;
}

#app {
  background: #fff;
  border-radius: 4px;
}

.slider {
  position: relative;
  overflow-x: hidden;
  border: 1px solid #cccccc;
  border-radius: 3px;
  height: 40px;
  margin-bottom: 4px;
}

.slider > div {
  position: absolute;
  width: 100%;
  text-align: center;
}

.animated {
  transition: transform .5s;
}
.slide-in-left {
  transform: translate(-100%, 0);
}
.slide-in-right {
  transform: translate(100%, 0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" v-cloak>
  <div class="slider">
    <transition name="slide"
      enter-active-class="animated"
      :enter-class="enterClass"
    >
      <div :key="step">
        Content <br />
        {{ step }}
      </div>
    </transition>
  </div>
  <button @click="--step">-</button>
  <button @click="++step">+</button>
</div>

Можете добавить leave-class таким же образом, если вы хотите сделать его красивее

Вы можете использовать GSAP. Я видел это на видео (ссылка с таймингом) https://youtu.be/14yOawLavB0?t=734 есть пример кода (вы можете легко использовать его своими шагами) и результат.

Другие вопросы по тегам