CollapseContainer.vue 3.0 KB
Newer Older
陈文彬 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
<template>
  <div class="collapse-container p-2 bg:white rounded-sm">
    <CollapseHeader v-bind="$props" :show="show" @expand="handleExpand" />
    <CollapseTransition :enable="canExpan">
      <Skeleton v-if="loading" />
      <div class="collapse-container__body" v-else v-show="show">
        <LazyContainer :timeout="lazyTime" v-if="lazy">
          <slot />
          <template v-slot:skeleton>
            <slot name="lazySkeleton" />
          </template>
        </LazyContainer>
        <slot />
      </div>
    </CollapseTransition>
  </div>
</template>
<script lang="ts">
  import type { PropType } from 'vue';

  import { defineComponent, ref, unref } from 'vue';
  // component
  import { CollapseTransition } from '/@/components/Transition/index';
  import CollapseHeader from './CollapseHeader.vue';
  import { Skeleton } from 'ant-design-vue';

  import LazyContainer from '../LazyContainer';

  import { triggerWindowResize } from '/@/utils/event/triggerWindowResizeEvent';
  // hook
  import { useTimeout } from '/@/hooks/core/useTimeout';
  export default defineComponent({
    components: { Skeleton, LazyContainer, CollapseHeader, CollapseTransition },
    name: 'CollapseContainer',
    props: {
      // 标题
      title: {
        type: String as PropType<string>,
        default: '',
      },
      // 是否可以展开
      canExpan: {
        type: Boolean as PropType<boolean>,
        default: true,
      },
      // 标题右侧温馨提醒
      helpMessage: {
        type: [Array, String] as PropType<string[] | string>,
        default: '',
      },
      // 展开收缩的时候是否触发window.resize,
      // 可以适应表格和表单,当表单收缩起来,表格触发resize 自适应高度
      triggerWindowResize: {
        type: Boolean as PropType<boolean>,
        default: false,
      },
      loading: {
        type: Boolean as PropType<boolean>,
        default: false,
      },
      // 延时加载
      lazy: {
        type: Boolean as PropType<boolean>,
        default: false,
      },
      // 延时加载时间
      lazyTime: {
        type: Number as PropType<number>,
        default: 3000,
      },
    },
    setup(props) {
      const showRef = ref(true);
      /**
       * @description: 处理开展事件
       */
      function handleExpand() {
        const hasShow = !unref(showRef);
        showRef.value = hasShow;

        if (props.triggerWindowResize) {
          // 这里200毫秒是因为展开有动画,
          useTimeout(triggerWindowResize, 200);
        }
      }
      return {
        show: showRef,
        handleExpand,
      };
    },
  });
</script>
<style lang="less">
  .collapse-container {
    padding: 10px;
    background: #fff;
    border-radius: 8px;
    transition: all 0.3s ease-in-out;

    &.no-shadow {
      box-shadow: none;
    }

    &__header {
      display: flex;
      height: 32px;
      margin-bottom: 10px;
      justify-content: space-between;
      align-items: center;
    }

    &__action {
      display: flex;
      align-items: center;
    }
  }
</style>