Переходы Vue.js: анимация высоты при использовании анимации выдвижения - PullRequest
0 голосов
/ 30 октября 2018

На моей странице есть несколько элементов, которые можно свернуть. Вот codepen для иллюстрации.

enter image description here

Vue.component('block', {
  template: '#block',
  props: [ 'title', 'items', 'collapsed' ],
});

new Vue({
  el: '#app',
  data: {
    first: [ 
      { name: 'Item 1' }, 
      { name: 'Item 2' }, 
      { name: 'Item 3' }
    ],
    second: [
      { name: 'Item 1' },
      { name: 'Item 2' },
      { name: 'Item 3' }
    ]
  }
});
#app {
  display: flex;
  flex-direction: column;
}
.block {
  $padding: 10px;
  margin: 20px;
  .title {
    color: white;
    background: grey;
    padding: $padding;
    font-weight: bold;
    font-size: 22px;
    cursor: pointer;
  }
  .list {
    position: relative;
    z-index: -1;
    padding: $padding;
    font-size: 16px;
    border: 1px solid lightgrey;
  }
  .list-item:not(:last-child) {
    padding-bottom: $padding;
  }
}

.slide-out-enter-active,
.slide-out-leave-active {
    transition: all 0.3s;
}

.slide-out-enter,
.slide-out-leave-to {
    opacity: 0;
    transform: translateY(-40px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<div id="app">
  <block :items="first" title="First block"></block>

  <block :items="second" title="Second block"></block>
</div>

<script type="text/x-template" id="block">
  <div class="block">
    <div class="title" @click="collapsed = !collapsed">{{ title }} (click to toggle)</div>
    <transition name="slide-out">
      <div v-if="!collapsed" class="list">
        <div class="list-item" v-for="item in items">
          {{item.name}}
        </div>
      </div>
    </transition>
  </div>
</script>

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

Есть мысли?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Вы также можете анимировать свойство margin одновременно с переводом. Смотрите этот пример кода

просто измените ваши enter и leave-to css на что-то вроде этого

.slide-out-enter,
.slide-out-leave-to {
    opacity: 0;
    transform: translateY(-100px);
    margin-bottom: -100px;
}
0 голосов
/ 30 октября 2018

Проблема заключается в том, что ваш макет не перекомпоновывается из-за характера свойства transform после добавления .list-item s к вашим .blocks s. Вы можете прочитать о 3 различных методах, которые могут использоваться для того, что вы делаете здесь .

Мое предложение использовать вместо этого свойство min-height, избавиться от перехода Vue и просто переключить класс на узле .list. Ниже приведены необходимые настройки:

CSS:

  // strip all of the .slide-out-* classes

  .list {
    ....
    max-height: 100px;
    transition: all 1s;
  }

  .block .list.is-collapsed {
    transition: all 1s;
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
  }

HTML:

удалить теги &

<div class="list" :class="{'is-collapsed': collapsed}">    <--- removed 'v-if'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...