VueJS transition css только скользит вниз


VueJS transition css только скользит вниз

03.10.2020 03:21:34 Просмотров 56 Источник

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

Я почти уверен, что это возможно только с помощью css. Пожалуйста, поправьте меня, если я ошибаюсь, но css-переходы с точки зрения производительности лучше, чем JS-переходы.

Итак, теперь HTML для Проблемы, с которой я столкнулся:

<transition name="slide-down">
  <ul v-if="isDisplayingOpeningHours" class="mt-2 text-sm flex flex-col space-y-2">
    <li v-for="i in 10" :key="i"> <!-- just for testing purposes -->
      element
    </li>
  </ul>
</transition>

А css-это:

.slide-down-enter-active, .slide-down-leave-active {
  transition: all .5s;
}

.slide-down-enter-to, .slide-down-leave {
  overflow: hidden;
  max-height: 100%;
}

.slide-down-enter, .slide-down-leave-to {
  overflow: hidden;
  max-height: 0;
}

Это приводит к не плавному переходу. Скольжение вниз не кажется проблемой,но когда он скользит вверх, он действительно дергается и совсем не бегает!. Если я установлю max-height: 10rem, это не сделает его лучше. Я надеюсь, что кто-то может отладить помочь мне с этой проблемой и, возможно, рассказать мне больше о переходах vue и переходах js vs css.

Редактировать:
Просто для уточнения самого перехода следует использовать только css. Открытие аккордеона происходит с помощью js, и это прекрасно. Кроме того, было бы неплохо, возможно, увидеть пример использования перехода с собственным компонентом vue-transition.

Правка 2:
Вот codesandbox, который имеет ту же проблему, что и я. https://codesandbox.io/s/frosty-bash-lmc2f?file=/src/components/HelloWorld.vue

У вопроса есть решение - Посмотреть?

Ответы - VueJS transition css только скользит вниз / Vuejs transition css only slide down

Является ответом!
Dipen Shah

05.10.2020 08:47:51

Еще Одно Обновление!!! Для того чтобы добиться перехода на JS, вы можете ознакомиться с официальным документом. В любом случае, я не собираюсь реализовывать причудливый механизм синхронизации, но в простейшей форме переход JS collapse в react будет выглядеть примерно так, я включил его в существующий codesandbox:

<template>
...
  <div>
    <button @click="jsOpen = !jsOpen">Open JS list</button>
    <transition
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:after-enter="afterEnter"
      v-on:enter-cancelled="enterCancelled"
      v-on:before-leave="beforeLeave"
      v-on:leave="leave"
      v-on:after-leave="afterLeave"
      v-on:level-cancelled="leaveCancelled"
      v-bind:css="false"
    >
      <ul v-if="jsOpen" class="mt-2 text-sm flex flex-col space-y-2">
        <li v-for="i in 10" :key="i">item-{{ i }}</li>
      </ul>
    </transition>
  </div>
</template>

<script>
export default {
  ...
  methods: {
    beforeEnter(el) {
      el.style.height = 0;
      el.style.overflow = "hidden";
    },
    enter(el, done) {
      const increaseHeight = () => {
        if (el.clientHeight < el.scrollHeight) {
          const height = `${parseInt(el.style.height) + 5}px`;
          el.style.height = height;
        } else {
          clearInterval(this.enterInterval);
          done();
        }
      };
      this.enterInterval = setInterval(increaseHeight, 10);
    },
    afterEnter(el) {},
    enterCancelled(el) {
      clearInterval(this.enterInterval);
    },
    beforeLeave(el) {},
    leave(el, done) {
      const decreaseHeight = () => {
        if (el.clientHeight > 0) {
          const height = `${parseInt(el.style.height) - 5}px`;
          el.style.height = height;
        } else {
          clearInterval(this.leaveInterval);
          done();
        }
      };
      this.leaveInterval = setInterval(decreaseHeight, 10);
    },
    afterLeave(el) {},
    leaveCancelled(el) {
      clearInterval(this.leaveInterval);
    },
  },
};
</script>

Обновление: После понимания требований от OP, я пытался играть с разными вещами, и я наткнулся на эту статью о css-трюках, которая объясняет гораздо более подробно о переходе, из этой статьи другое не-js решение, предложенное будет выглядеть следующим образом, я включил его в существующий stackblitz:

.scale-enter-active,
.scale-leave-active {
  transform-origin: top;
  transition: transform 0.3s ease-in-out;
}

.scale-enter-to,
.scale-leave-from {
  transform: scaleY(1);
}

.scale-enter-from,
.scale-leave-to {
  transform: scaleY(0);
}

здесь вместо высоты он масштабируется по оси Y. Он также имеет побочный эффект, заключающийся в том, что сначала он расширяет контейнер до полного размера, а затем обновляет (масштабирует) содержимое.

Вью В3.х Классы -leave и -enter в V3 переименованы в -leave-from и -enter-from. Взгляните на этого штакблица.

.slidedown-enter-active,
.slidedown-leave-active {
  transition: max-height 0.5s ease-in-out;
}

.slidedown-enter-to,
.slidedown-leave-from {
  overflow: hidden;
  max-height: 1000px;
}

.slidedown-enter-from,
.slidedown-leave-to {
  overflow: hidden;
  max-height: 0;
}

Вью версии v2.х Проблема в том, что вы указываете max-height на 100%, используйте некоторое значение, которое будет больше вашей ожидаемой максимальной высоты. Обновите свой стиль до:

.slide-down-enter-active,
.slide-down-leave-active {
  transition: max-height 0.5s ease-in-out;
}

.slide-down-enter-to,
.slide-down-leave {
  overflow: hidden;
  max-height: 1000px;
}

.slide-down-enter,
.slide-down-leave-to {
  overflow: hidden;
  max-height: 0;
}

и это должно сработать. Взгляните на эту демо-версию codesandbox.

Помочь в развитии проекта:
Закрыть X