Przeglądaj źródła

중첩 컴포넌트 slot 적용

김보경 5 lat temu
rodzic
commit
b307c1d39f
3 zmienionych plików z 195 dodań i 0 usunięć
  1. 99 0
      components/ProductHero.vue
  2. 80 0
      components/ProductHeroCard.vue
  3. 16 0
      pages/courses/_slug.vue

+ 99 - 0
components/ProductHero.vue

@@ -0,0 +1,99 @@
+<template>
+  <section
+    class="hero is-black">
+    <div class="hero-body">
+      <div class="hero-img">
+      </div>
+      <div class="container">
+        <div class="columns">
+          <div class="column is-9">
+            <h1 class="title">
+              {{title}}
+            </h1>
+            <h2 class="subtitle">
+              {{subtitle}}
+            </h2>
+            <div class="sub-subtitle">
+              <user-tile
+                :name="author.name"
+                :avatar="author.avatar" />
+            </div>
+          </div>
+          <div class="column is-3">
+            <div class="column-right">
+              <slot></slot>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </section>
+</template>
+<script>
+import UserTile from '~/components/shared/UserTile'
+export default {
+  components: {
+    UserTile
+  },
+  props: {
+    title: {
+      type: String,
+      default: 'Some Default Catchy Title'
+    },
+    subtitle: {
+      type: String,
+      default: 'Some Default Catchy Subtitle'
+    },
+    author: {
+      type: Object,
+      default: null
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+  .hero-body {
+    position: relative;
+  }
+  .hero-img {
+    opacity: 0.8;
+    position: absolute;
+    height: 100%;
+    width: 100%;
+    top: 0;
+    left: 0;
+    -webkit-background-size: cover;
+    -moz-background-size: cover;
+    -o-background-size: cover;
+    background-size: cover;
+    filter: sepia(.1) grayscale(.1) saturate(.8);
+  }
+  .column-right {
+    position: absolute;
+  }
+   @media screen and (max-width: 770px) {
+    .column-right {
+      position: inherit;
+    }
+  }
+  .user-avatar {
+    display: inline-block;
+  }
+  .is-black {
+    background-color: black;
+    background: linear-gradient(#29303B,#29303B,#29303B);
+  }
+  .title {
+    font-weight: bold;
+    font-size: 45px;
+  }
+  .subtitle {
+    /*font-weight: bold;*/
+    font-size: 25px;
+  }
+  .author-name {
+    font-size: 20px;
+    font-weight: bold;
+  }
+</style>

+ 80 - 0
components/ProductHeroCard.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="card ">
+    <div class="card-image">
+      <figure class="image is-4by2">
+        <img :src="image" alt="Placeholder image">
+      </figure>
+    </div>
+    <div class="card-content">
+      <div class="content m-b-sm">
+        <div class="media-content">
+          <span class="title is-2 main-price">${{price}}</span>
+          <span class="title is-2">${{discountedPrice}}</span>
+        </div>
+      </div>
+      <a
+        :href="navigateTo"
+        target="_"
+        class="button is-fullwidth is-large is-danger is-outlined m-b-sm">
+        Enroll on Udemy
+      </a>
+      <div class="content">
+        <div class="m-b-none course-features">Course Requirements</div>
+        <ul class="m-t-none">
+          <li v-for="req in requirements" :key="req.value">
+            {{req.value}}
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    requirements: {
+      type: Array,
+      default: null
+    },
+    price: {
+      type: Number,
+      default: null
+    },
+    navigateTo: {
+      type: String,
+      default: ''
+    },
+    discountedPrice: {
+      type: Number,
+      required: true
+    },
+    image: {
+      type: String,
+      required: false
+    }
+  }
+}
+</script>
+<style scoped lang="scss">
+  .card {
+    z-index: 9999;
+    min-width: 330px;
+    padding: 5px;
+    border-radius: 5px;
+    box-shadow: 0 0 1px 1px rgba(20,23,28,.1), 0 3px 1px 0 rgba(20,23,28,.1);
+    .title {
+      color: gray;
+    }
+    .subtitle {
+      color: gray;
+    }
+    .course-features {
+      font-size: 17px;
+    }
+    .main-price {
+      font-size: 17px;
+      color: #7d7d7d;
+      text-decoration: line-through;
+    }
+  }
+</style>

+ 16 - 0
pages/courses/_slug.vue

@@ -1,5 +1,16 @@
 <template>
   <div>
+    <product-hero
+      :title="course.title"
+      :subtitle="course.subtitle"
+      :author="course.author">
+      <product-hero-card
+        :price="course.price"
+        :discountedPrice="course.discountedPrice"
+        :navigateTo="course.productLink"
+        :requirements="course.requirements"
+        :image="course.image" />
+    </product-hero>
     <div class="container">
       <div class="columns">
         <div class="column is-9">
@@ -32,7 +43,12 @@
   </div>
 </template>
 <script>
+import ProductHero from '~/components/ProductHero'
+import ProductHeroCard from '~/components/ProductHeroCard'
 export default {
+  components: {
+    ProductHero, ProductHeroCard
+  },
   computed: {
     course() {
       return this.$store.state.course.item