1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- <template>
- <transition v-on="on">
- <slot />
- </transition>
- </template>
- <script>
- import { defineComponent } from 'vue-demi';
- import { inlineStyle } from '../../utils/dom';
- export default defineComponent({
- name: 'mCollapseTransition',
- props: {
- duration: {
- type: Number,
- default: 0.5,
- },
- animate: {
- type: String,
- default: 'ease',
- }
- },
- setup(props) {
- const getStyle = (obj) => {
- if (obj.currentStyle) {
- return obj.currentStyle;
- }
- return obj.currentStyle || getComputedStyle(obj);
- }
- const transition = (config) => {
- const style = {
- transition: `all ${config.duration}s ${config.animate}`,
- overflow: 'hidden',
- };
- return {
- beforeEnter(el) {
- el.dataset.paddingTop = getStyle(el).paddingTop; // el.style.paddingTop
- el.dataset.paddingBottom = getStyle(el).paddingBottom; // el.style.paddingBottom
- inlineStyle(
- el,
- Object.assign(style, { height: 0 }),
- );
- },
- enter(el) {
- setTimeout(() => {
- inlineStyle(el, {
- height: `${el.scrollHeight}px`,
- paddingTop: el.dataset.paddingTop,
- paddingBottom: el.dataset.paddingBottom,
- });
- }, 0);
- },
- afterEnter(el) {
- inlineStyle(el, { height: '', overflow: '' });
- },
- beforeLeave(el) {
- inlineStyle(el, Object.assign(style, {
- height: `${el.scrollHeight}px`,
- overflow: '',
- }));
- },
- leave(el) {
- setTimeout(() => {
- inlineStyle(el, { height: 0, overflow: 'hidden' });
- }, 0);
- },
- afterLeave(el) {
- inlineStyle(el, { height: 0, overflow: 'hidden' });
- },
- };
- }
- return {
- on: transition(props)
- }
- }
- })
- </script>
|