在我的Vue应用程序中,我有一个简单的切换按钮,可以在 Activity 时显示一个列表。该列表不应立即出现/消失。我想在渲染上有一个平滑的向下滑动过渡,在隐藏上有一个平滑的向上滑动过渡。
以下代码显示了到目前为止的内容,有人知道如何使它工作吗?

new Vue({
  el: '#app',
  data: () => ({
    isOpen: true,
  }),
});
.expand-enter-active,
.expand-leave-active {
  overflow: hidden;
  transition: height .5s linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <button @click="isOpen = !isOpen">
    is open: {{ isOpen }}
  </button>
  <transition name="expand">
    <div v-if="isOpen">
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </div>
  </transition>
</div>

最佳答案

请看看这个解决方案。

Vue.component('transition-collapse-height', {
  template: `<transition
    enter-active-class="enter-active"
    leave-active-class="leave-active"
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter"
    @before-leave="beforeLeave"
    @leave="leave"
    @after-leave="afterLeave"
  >
    <slot />
  </transition>`,
  methods: {
    /**
     * @param {HTMLElement} element
     */
    beforeEnter(element) {
      requestAnimationFrame(() => {
        if (!element.style.height) {
          element.style.height = '0px';
        }

        element.style.display = null;
      });
    },
    /**
     * @param {HTMLElement} element
     */
    enter(element) {
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          element.style.height = `${element.scrollHeight}px`;
        });
      });
    },
    /**
     * @param {HTMLElement} element
     */
    afterEnter(element) {
      element.style.height = null;
    },
    /**
     * @param {HTMLElement} element
     */
    beforeLeave(element) {
      requestAnimationFrame(() => {
        if (!element.style.height) {
          element.style.height = `${element.offsetHeight}px`;
        }
      });
    },
    /**
     * @param {HTMLElement} element
     */
    leave(element) {
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          element.style.height = '0px';
        });
      });
    },
    /**
     * @param {HTMLElement} element
     */
    afterLeave(element) {
      element.style.height = null;
    },
  },
});

new Vue({
  el: '#app',
  data: () => ({
    isOpen: true,
  }),
});
.enter-active,
.leave-active {
  overflow: hidden;
  transition: height .5s linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <button @click="isOpen = !isOpen">
    is open: {{ isOpen }}
  </button>
  <transition-collapse-height>
    <div v-show="isOpen">
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </div>
  </transition-collapse-height>
</div>

07-26 03:40