HomeCard.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <script setup lang="ts">
  2. import { toRefs, computed } from "vue";
  3. import { useRouter } from "vitepress";
  4. import _ from "lodash";
  5. const props = withDefaults(
  6. defineProps<{
  7. title?: string;
  8. color?: "info" | "skyblue" | "white";
  9. link?: string;
  10. backgroundStyle?: Record<string, string>;
  11. }>(),
  12. {
  13. color: "info",
  14. backgroundStyle: { right: "16px", bottom: "24px" },
  15. }
  16. );
  17. const router = useRouter();
  18. const { title, color } = toRefs(props);
  19. const styles = computed(() => {
  20. return _.get(
  21. {
  22. primary: {
  23. backgroundColor: "#f5f9ff",
  24. borderColor: "#e2eeff",
  25. '--card-title-color': '#2B67CA',
  26. },
  27. info: {
  28. backgroundColor: "#f5f9ff",
  29. borderColor: "#e2eeff",
  30. },
  31. skyblue: {
  32. backgroundColor: "#f6fdff",
  33. borderColor: "#e3f8f4",
  34. '--card-title-color': '#2AA58B',
  35. },
  36. white: {
  37. borderColor: "#e2eeff",
  38. backgroundColor: "#fff",
  39. },
  40. },
  41. color.value
  42. );
  43. });
  44. const onClick = () => {
  45. if (props.link) {
  46. router.go(props.link);
  47. }
  48. };
  49. </script>
  50. <template>
  51. <div class="card" :class="{ 'is-link': !!link }" :style="styles" @click="onClick">
  52. <div v-if="$slots.background" class="background" :style="props.backgroundStyle">
  53. <slot name="background"> </slot>
  54. </div>
  55. <slot name="title">
  56. <h2 v-if="title">
  57. {{ title }}
  58. </h2>
  59. </slot>
  60. <el-row :gutter="20" tag="section">
  61. <slot></slot>
  62. </el-row>
  63. </div>
  64. </template>
  65. <style lang="scss" scoped>
  66. @use '@/.vitepress/theme/screen' as *;
  67. :slotted(:deep(h2)),
  68. h2 {
  69. border: none;
  70. margin: 0;
  71. padding: 0;
  72. }
  73. .card {
  74. width: 100%;
  75. height: 100%;
  76. position: relative;
  77. display: flex;
  78. flex-direction: column;
  79. align-items: stretch;
  80. gap: 24px;
  81. border-radius: 20px;
  82. padding: 32px;
  83. background: #f5f9ff;
  84. border: 1px solid #e2eeff;
  85. min-height: 240px;
  86. :deep(.card) {
  87. min-height: 162px;
  88. }
  89. &.is-link {
  90. cursor: pointer;
  91. }
  92. .background {
  93. position: absolute;
  94. }
  95. h2 {
  96. color: var(--card-title-color);
  97. display: flex;
  98. align-items: center;
  99. .prefix {
  100. margin-right: 8px;
  101. }
  102. .suffix {
  103. width: 24px;
  104. height: 24px;
  105. margin-left: 8px;
  106. color: #00000042;
  107. }
  108. }
  109. .el-row {
  110. row-gap: 20px;
  111. align-items: stretch;
  112. }
  113. }
  114. @include breakpoint(mobile) {
  115. .card {
  116. padding: 16px;
  117. min-height: 120px;
  118. gap: 12px;
  119. min-height: 130px;
  120. :deep(.card) {
  121. min-height: 130px;
  122. padding: 24px;
  123. }
  124. }
  125. }
  126. </style>