๐ฏ ํ์ต ๋ชฉํ
- ๋ฉ์ธ ์ฌ๋ผ์ด๋ ์ค๋ฅธ์ชฝ ์์ญ์ ์๋ ์ฝํ ์ธ ๋ฆฌ์คํธ ๊ตฌํ
- ๊ฐ ์ฝํ
์ธ ๋:
- ์์ด์ฝ or ์ธ๋ค์ผ ์ด๋ฏธ์ง
- ์ ๋ชฉ + ์งง์ ์ค๋ช
- 1์ด ์ธ๋ก ๋ฐฐ์น ์นด๋ + ๋ฐ์ํ ๋์ ํฌํจ
โ ๊ตฌ์ฑ ์์
ํญ๋ชฉ | ๋ด์ฉ |
---|---|
๊ตฌ์กฐ | MainRightContent.vue |
ํ์ ์ปดํฌ๋ํธ | RightCard.vue (์ฝํ
์ธ 1๊ฐ ์นด๋) |
๋ฐฐ์น ์์น | StickyPanel.vue ๋ด๋ถ (๊ธฐ์กด MainSlide ์ฐ์ธก์ ๊ณ ์ ๋ ์์ญ) |
๐ ํด๋ ๊ตฌ์ฑ
components/
โโโ MainRightContent.vue โ ์ ์ฒด ๋ฆฌ์คํธ
โโโ RightCard.vue โ ์ฝํ
์ธ ์นด๋ 1๊ฐ
โโโ StickyPanel.vue โ ๊ธฐ์กด ํ์ผ, ๋ด๋ถ์ MainRightContent ์ถ๊ฐ
โโโ TeacherPromoSection.vue โ ๊ธฐ์กด ํ์ผ, scss ์์
views
โโโ HomePage.vue โ ๋ฉ์ธ ํ์ด์ง scss ์์
โ
1. RightCard.vue
<template>
<div class="right-card">
<img class="icon" :src="img" :alt="title" />
<div class="text">
<p class="title">{{ title }}</p>
<p class="desc">{{ description }}</p>
</div>
</div>
</template>
<script>
export default {
name: "RightCard",
props: {
img: String,
title: String,
description: String,
},
};
</script>
<style lang="scss" scoped>
.right-card {
display: flex;
align-items: center;
margin-bottom: 22px;
transition: 0.2s ease;
&:last-of-type {
margin-bottom: 0;
}
}
.icon {
width: 140px;
height: 90px;
object-fit: cover;
margin-right: 12px;
border-radius: 8px;
}
.text .title {
font-size: 14px;
font-weight: bold;
margin-bottom: 4px;
}
.text .desc {
font-size: 12px;
color: #666;
}
</style>
โ
2. MainRightContent.vue
<template>
<div class="right-section">
<RightCard
v-for="(item, i) in items"
:key="i"
:img="item.img"
:title="item.title"
:description="item.description"
/>
</div>
</template>
<script>
import RightCard from "./RightCard.vue";
export default {
components: { RightCard },
data() {
return {
items: [
{
img: "https://files.megagong.net/board_data/banner/main/97372942848_20250718175514.png",
title: "2026 ์ปค๋ฆฌํ๋ผ ์๋ด",
description: "์ ๋ฒ์ ํํํ ๊ฐ๋
์ดํด์ \n์ถ๋ก ํ๋ จ์ผ๋ก ๊ณ ๋์ ์์ฑ",
},
{
img: "https://files.megagong.net/board_data/banner/main/111851706690_20250711084722.png",
title: "2026 ํ์ ํ ์ปค๋ฆฌํ๋ผ",
description: "์ ๋ฒ์ ํํํ ๊ฐ๋
์ดํด์ \n์ถ๋ก ํ๋ จ์ผ๋ก ๊ณ ๋์ ์์ฑ",
},
{
img: "https://files.megagong.net/board_data/banner/main/60393398016_20250623113547.png",
title: "7-8์ ์
๋ฐ์ดํธ ๊ฐ์ข",
description: "์ต์ ์ปค๋ฆฌํ๋ผ ๋ฐ์!",
},
],
};
},
};
</script>
<style scoped>
.right-section {
display: flex;
flex-direction: column;
padding: 30px;
border: 1px solid #ddd;
border-radius: 20px;
}
</style>
โ
3. StickyPanel.vue
์ ์ฝ์
๋ฐ sticky ๊ธฐ๋ฅ ์ถ๊ฐ
<template>
<div class="sticky-panel">
<MainRightContent />
</div>
</template>
<script>
import MainRightContent from "./MainRightContent.vue";
export default {
components: { MainRightContent },
};
</script>
<style scoped>
.sticky-panel {
position: sticky;
top: 30px;
}
</style>
โ
4. views/Homepage.vue
์ scss ์ ์ฒด ์์
<style lang="scss" scoped>
.layout-container {
display: flex;
position: relative;
}
.main-content {
display: flex;
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 40px 0;
gap: 30px;
}
.main-left {
display: flex;
flex-direction: column;
width: 790px;
gap: 30px;
}
.main-right {
width: 380px;
position: relative;
top: 0;
gap: 30px;
}
</style>
โ
5. components/TeacherPromoSection.vue
์ css ๋ถ๋ถ ์์
<style scoped>
.teacher-promo-section {
/* margin-top: 60px; */
padding: 0 20px;
width: 790px;
}
.section-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 24px;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
</style>
โ ๊ฒฐ๊ณผ
MainSlide
์ค๋ฅธ์ชฝ์ ์ ์ ์ธ ์ธ๋ก ์นด๋๋ค์ด ๋ํ๋จ- ํฅํ โ๊ธฐํ์ โ, โ๋ฌด๋ฃ ์ฝํ ์ธ โ, โํ๋ณด๋ฐฐ๋โ ๋ฑ์ ๋ด์ฉ์ผ๋ก ํ์ฅ ๊ฐ๋ฅ
- PC ํ๋ฉด ๊ธฐ์ค ๋๋น ์ฝ
300px
์ด์์ผ๋ก ๊ณ ์ ,position: sticky
๊ฐ๋ฅ
GitHub - heroyooi/vue2-megagong at ch5
๐ฏ ๋ค์ ๊ณผ์
์๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํด๋ณด์ธ์!
MainRightSlide.vue
์๋ก์ด ์ปดํฌ๋ํธ๋ฅผ ์์ฑํด์ ์ ์ฒด ์ฌ๋ผ์ด๋๋ก ๊ตฌํ
๐ฌ ๋๊ธ
โป ๋ก๊ทธ์ธ ํ ๋๊ธ์ ์์ฑํ ์ ์์ต๋๋ค.