index.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <script setup lang="ts">
  2. defineProps({
  3. title: {
  4. type: String,
  5. default: ''
  6. },
  7. subtitle: {
  8. type: String,
  9. default: ''
  10. },
  11. dark: {
  12. type: Boolean,
  13. default: false
  14. },
  15. bgImage: {
  16. type: String,
  17. default: ''
  18. },
  19. bgColor: {
  20. type: String,
  21. default: ''
  22. },
  23. heroSection: {
  24. type: Boolean,
  25. default: false
  26. },
  27. centered: {
  28. type: Boolean,
  29. default: false
  30. }
  31. })
  32. </script>
  33. <template>
  34. <section
  35. class="section"
  36. :class="{
  37. 'dark': dark,
  38. 'hero-section': heroSection,
  39. 'centered': centered
  40. }"
  41. :style="{
  42. backgroundImage: bgImage ? `url('${bgImage}')` : 'none',
  43. backgroundColor: bgColor || ''
  44. }"
  45. >
  46. <div v-if="title || subtitle" class="section-header">
  47. <h2 v-if="title" class="headline">{{ title }}</h2>
  48. <p v-if="subtitle" class="description">{{ subtitle }}</p>
  49. </div>
  50. <div class="section-content">
  51. <slot></slot>
  52. </div>
  53. </section>
  54. </template>
  55. <style lang="scss" scoped>
  56. @use '@/assets/styles/variables' as v;
  57. @use '@/assets/styles/mixins' as m;
  58. .section {
  59. padding: v.$spacing-xxxl 0;
  60. position: relative;
  61. &.dark {
  62. color: v.$text-color-light;
  63. }
  64. &.hero-section {
  65. background-size: cover;
  66. background-position: center;
  67. min-height: 400px;
  68. @include m.flex-column;
  69. justify-content: center;
  70. }
  71. &.centered {
  72. text-align: center;
  73. .section-content {
  74. @include m.flex-column;
  75. align-items: center;
  76. }
  77. }
  78. .section-header {
  79. @include m.flex-column;
  80. align-items: center;
  81. justify-content: center;
  82. text-align: center;
  83. max-width: v.$content-max-width;
  84. margin: 0 auto v.$spacing-xl;
  85. min-height: 100px; // 确保有足够的空间进行垂直居中
  86. .headline {
  87. font-size: v.$font-size-xxl;
  88. margin-bottom: v.$spacing-md;
  89. width: 100%;
  90. display: flex;
  91. align-items: center;
  92. justify-content: center;
  93. }
  94. .description {
  95. font-size: v.$font-size-md;
  96. line-height: 1.6;
  97. width: 100%;
  98. display: flex;
  99. align-items: center;
  100. justify-content: center;
  101. }
  102. }
  103. .section-content {
  104. max-width: v.$container-width;
  105. margin: 0 auto;
  106. padding: 0 v.$spacing-md;
  107. @include m.flex-column;
  108. align-items: center;
  109. justify-content: center;
  110. // 如果section-content内部有需要占满宽度的元素,可以使用以下样式
  111. :deep(> *) {
  112. width: 100%;
  113. }
  114. }
  115. }
  116. </style>