【vue】记录收缩展开的动画效果

发布时间 2023-04-20 21:24:07作者: 三勺

前言

项目里有时候使用到类似于收缩展开的功能,不设置动画会显得过程很生硬,记录下项目里有使用过的收缩展开的动画实现方式。

方式一:element UI 的折叠动画

如果项目使用到 element UI 可以引入如下组件,实现动画效果:
1、引入组件

import 'element-ui/lib/theme-chalk/base.css';
import CollapseTransition from 'element-ui/lib/transitions/collapse-transition';

export default {
  components:{
    CollapseTransition
  }
}

2、使用组件

<div style="width: 500px;position: relative">
      <div style="background: pink;display: flex;align-items: center;justify-content: space-between;padding: 0 10px">
        <span>标题</span>
        <span @click="change" style="cursor: pointer">{{!show?'展开':'收缩'}}</span>
      </div>
      <collapse-transition>
              <div v-if="show"
                   style="position: absolute;top: 24px;left: 0;right: 0;background: darkorange;">
                <div style="height: 300px;display: flex;align-items: center;justify-content: center">内容</div>
              </div>
      </collapse-transition>
    </div>

方式二:引入如下js

1、创建 collapseTransition.js

/* 视图伸缩动画效果组件 */
/* jshint esversion: 6 */
const elTransition = '0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out';
const Transition = {
  'before-enter' (el) {
    el.style.transition = elTransition;
    if (!el.dataset) el.dataset = {};
 
    el.dataset.oldPaddingTop = el.style.paddingTop;
    el.dataset.oldPaddingBottom = el.style.paddingBottom;
 
    el.style.height = 0;
    el.style.paddingTop = 0;
    el.style.paddingBottom = 0;
  },
 
  'enter' (el) {
    el.dataset.oldOverflow = el.style.overflow;
    if (el.scrollHeight !== 0) {
      el.style.height = el.scrollHeight + 'px';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    } else {
      el.style.height = '';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    }
 
    el.style.overflow = 'hidden';
  },
 
  'after-enter' (el) {
    el.style.transition = '';
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
  },
 
  'before-leave' (el) {
    if (!el.dataset) el.dataset = {};
    el.dataset.oldPaddingTop = el.style.paddingTop;
    el.dataset.oldPaddingBottom = el.style.paddingBottom;
    el.dataset.oldOverflow = el.style.overflow;
 
    el.style.height = el.scrollHeight + 'px';
    el.style.overflow = 'hidden';
  },
 
  'leave' (el) {
    if (el.scrollHeight !== 0) {
      el.style.transition = elTransition;
      el.style.height = 0;
      el.style.paddingTop = 0;
      el.style.paddingBottom = 0;
    }
  },
 
  'after-leave' (el) {
    el.style.transition = '';
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
    el.style.paddingTop = el.dataset.oldPaddingTop;
    el.style.paddingBottom = el.dataset.oldPaddingBottom;
  }
};
 
export default {
  name: 'collapseTransition',
  functional: true,
  render (h, { children }) {
    const data = {
      on: Transition
    };
    return h('transition', data, children);
  }
};

2、引入使用

import CollapseTransition from './collapseTransition'
components:{
   CollapseTransition
},
<collapse-transition>
              <div v-if="show"
                   style="position: absolute;top: 24px;left: 0;right: 0;background: darkorange;">
                <div style="height: 300px;display: flex;align-items: center;justify-content: center">内容</div>
              </div>
      </collapse-transition>

实现效果

image