折叠动画

197 阅读1分钟

组件 CollapseTransition.js

const transitionStyle = '0.4s height ease-in-out';
const Transition = {
  beforeEnter (el) {
    el.style.transition = transitionStyle;
    if (!el.dataset) el.dataset = {};

    el.style.height = 0;
  },

  enter (el) {
    if (el.scrollHeight !== 0) {
      el.style.height = `${el.scrollHeight}px`;
    } else {
      el.style.height = '';
    }
    el.style.overflow = 'hidden';
  },

  afterEnter (el) {
    el.style.transition = '';
    el.style.height = '';
  },

  beforeLeave (el) {
    if (!el.dataset) el.dataset = {};
    el.style.height = `${el.scrollHeight}px`;
    el.style.overflow = 'hidden';
  },

  leave (el) {
    if (el.scrollHeight !== 0) {
      el.style.transition = transitionStyle;
      el.style.height = 0;
    }
  },

  afterLeave (el) {
    el.style.transition = '';
    el.style.height = '';
  },
};

export default {
  name: 'CollapseTransition',
  functional: true,
  render (h, { children }) {
    const data = {
      on: Transition,
    };
    return h('transition', data, children);
  },
};

使用

<template>
  <div class=''>
    <button @click="handleShowHidden">控制折叠</button>
    <collapse-transition>
      <div v-if="show">
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
        <div>折叠内容</div>
      </div>
    </collapse-transition>
  </div>
</template>

<script>
import CollapseTransition from '@/components/CollapseTransition.js'
export default {
  components: { CollapseTransition },
  props: {},
  data () {
    return {
      show: false
    }
  },
  methods: {
    handleShowHidden () {
      this.show = !this.show;
    }
  },
}
</script>

效果

折叠动画.gif