ContentWrap.vue 2.33 KB
<script setup lang="ts">
import { ElCard, ElTooltip } from "element-plus";
import { CaretBottom, CaretRight } from "@element-plus/icons-vue";
import { useElementSize } from "@vueuse/core";

const props = defineProps({
  expandSwicth: {
    type: Boolean,
    default: false,
  }, // 展开收起按钮
  title: {
    type: String,
    default: "",
  },
  description: {
    type: String,
    default: "",
  },
  isExpand: {
    type: Boolean,
    default: true,
  },
});

const emits = defineEmits(["expand"]);

const isExpanded = ref(true);

watch(
  () => props.isExpand,
  (v) => {
    isExpanded.value = v;
  }
);

const contentRef = ref();
const { height: contentHeight } = useElementSize(contentRef);

const expandSwicthHandler = () => {
  if (!props.expandSwicth) {
    return;
  }
  isExpanded.value = !isExpanded.value;
  emits("expand", isExpanded.value);
};
</script>

<template>
  <ElCard
    class="v-content-wrap"
    shadow="never"
    :body-style="{
      padding: `0px`,
      height: `${isExpanded ? contentHeight + 28 : 0}px`,
    }"
  >
    <template v-if="title" #header>
      <div class="card-title" @click="expandSwicthHandler">
        <span v-if="expandSwicth" style="padding-right: 5px; cursor: pointer">
          <el-icon :size="21" v-if="isExpanded">
            <CaretBottom />
          </el-icon>
          <el-icon :size="21" v-else>
            <CaretRight />
          </el-icon>
        </span>
        <span class="title">{{ title }}</span>
        <span class="desc"> {{ description }}</span>
        <div class="">
          <slot name="header"></slot>
        </div>
      </div>
    </template>
    <div ref="contentRef" class="card-body-content">
      <slot></slot>
    </div>
  </ElCard>
</template>

<style lang="scss" scoped>
.v-content-wrap {
  border-radius: 0;

  :deep .el-card__header {
    background-color: #fafafa;
    cursor: pointer;
  }

  :deep .el-card__body {
    transition: height 0.3s;
    overflow: hidden;
  }

  .card-body-content {
    padding: 16px 16px 12px 16px;
  }

  .card-title {
    display: flex;
    align-items: center;

    .title {
      font-size: 14px;
      color: var(--el-text-color-primary);
      line-height: 21px;
      font-weight: 600;
    }

    .desc {
      font-size: 14px;
      color: #999999;
      line-height: 21px;
      font-weight: 400;
      margin-left: 8px;
    }
  }
}
</style>