ProductCard.vue 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <template>
  2. <div class="product--card" :data-layout="layout" :data-image-position="imagePosition">
  3. <div class="product--card--thumb">
  4. <img :src="image" :alt="imageAlt || title" loading="lazy" />
  5. </div>
  6. <div class="product--card--content">
  7. <h2 v-if="title" class="product--card--title">{{ title }}</h2>
  8. <h3 v-if="subtitle" class="product--card--subtitle">{{ subtitle }}</h3>
  9. <div v-if="description" class="product--card--description">
  10. <p>{{ description }}</p>
  11. </div>
  12. <div v-if="buttonText && buttonUrl" class="product--card--actions">
  13. <NuxtLink :to="buttonUrl" :target="buttonTarget" class="default--round--btn">
  14. {{ buttonText }}
  15. </NuxtLink>
  16. </div>
  17. <div v-if="$slots.actions" class="product--card--actions">
  18. <slot name="actions"></slot>
  19. </div>
  20. </div>
  21. </div>
  22. </template>
  23. <script setup>
  24. // Props 정의
  25. const props = defineProps({
  26. // 이미지 관련
  27. image: {
  28. type: String,
  29. required: true,
  30. },
  31. imageAlt: {
  32. type: String,
  33. default: "",
  34. },
  35. // 텍스트 관련
  36. title: {
  37. type: String,
  38. required: true,
  39. },
  40. subtitle: {
  41. type: String,
  42. default: "",
  43. },
  44. description: {
  45. type: String,
  46. default: "",
  47. },
  48. // 버튼 관련
  49. buttonText: {
  50. type: String,
  51. default: "",
  52. },
  53. buttonUrl: {
  54. type: String,
  55. default: "/",
  56. },
  57. buttonTarget: {
  58. type: String,
  59. default: "_self",
  60. validator: (value) => ["_self", "_blank"].includes(value),
  61. },
  62. // 레이아웃 옵션
  63. layout: {
  64. type: String,
  65. default: "horizontal", // 'horizontal', 'vertical'
  66. validator: (value) => ["horizontal", "vertical"].includes(value),
  67. },
  68. // 이미지 위치 옵션
  69. imagePosition: {
  70. type: String,
  71. default: "left", // 'left', 'right'
  72. validator: (value) => ["left", "right"].includes(value),
  73. },
  74. });
  75. </script>