๐ฏ ํ์ต ๋ชฉํ
- ๋ฉ๊ฐ๊ณต๋ฌด์ ๋ฉ์ธ์ฒ๋ผ ํญ ํด๋ฆญ ์ ์ฝํ ์ธ ๊ฐ ๋ณ๊ฒฝ๋๋ ์ฌ๋ผ์ด๋๋ฅผ ๊ตฌํํฉ๋๋ค.
MainTabs.vue
์ปดํฌ๋ํธ ๋ด๋ถ์ Swiper๋ฅผ ์ฐ๋ํ๊ณ , ์ ํ๋ ํญ์ ๋ฐ๋ผ ์ฌ๋ผ์ด๋ ์ฝํ ์ธ ๊ฐ ๋์ ์ผ๋ก ๋ฐ๋๊ฒ ๋ง๋ญ๋๋ค.
๐ ํ์ผ ๊ตฌ์กฐ
src/
โโโ components/
โ โโโ MainTabs.vue
โ โโโ TabSlide.vue โ ์๋ก ์์ฑ
๐งฉ 1. MainTabs.vue
๊ตฌํ
<template>
<div class="main-tabs">
<h3 class="title">๋ฅ์คํธ๊ณต๋ฌด์ 1์ ๊ฐ์ฌ์ง</h3>
<div class="tab-slide">
<div class="tabs">
<button
v-for="(tab, idx) in tabs"
:key="idx"
:class="{ active: currentTab === idx }"
@click="changeTab(idx)"
>
{{ tab.label }}
</button>
</div>
<TabSlide v-if="mounted" :key="renderKey" :slides="tabs[currentTab].slides" />
</div>
</div>
</template>
<script>
import TabSlide from "./TabSlide.vue";
export default {
components: { TabSlide },
data() {
return {
currentTab: 0,
renderKey: 0,
mounted: true,
tabs: [
{
label: "๊ตญ์ด",
slides: [
{
img: "https://img.megagong.net/profphoto/gong/gilltoraebi/main_intro.png",
alt: "์ด์ค์ฃผ",
},
{
img: "https://img.megagong.net/profphoto/gong/jhssam1003/main_intro.png",
alt: "์์งํ",
},
],
},
{
label: "์์ด",
slides: [
{
img: "https://img.megagong.net/profphoto/gong/tjenglish08/main_intro.png",
alt: "์กฐํ์ ",
},
{
img: "https://img.megagong.net/profphoto/gong/megamega2/main_intro.png",
alt: "์ฑ์ ํ",
},
{
img: "https://img.megagong.net/profphoto/gong/incredvoc/main_intro.png",
alt: "๊ฒฝ์ ์",
},
{
img: "https://img.megagong.net/profphoto/gong/nojoony1/main_intro.png",
alt: "๋ฐ๋
ธ์ค",
},
],
},
{
label: "ํ๊ตญ์ฌ",
slides: [
{
img: "https://img.megagong.net/profphoto/gong/gosabu88/main_intro.png",
alt: "๊ณ ์ข
ํ",
},
{
img: "https://img.megagong.net/profphoto/gong/vision0911/main_intro.png",
alt: "๋ผ์ํ",
},
{
img: "https://img.megagong.net/profphoto/gong/duwo20405/main_intro.png",
alt: "์ต์์ฌ",
},
{
img: "https://img.megagong.net/profphoto/gong/jeonhangil/main_intro.png",
alt: "์ ํ๊ธธ",
},
],
},
{
label: "ํ์ ํ",
slides: [
{
img: "https://img.megagong.net/profphoto/gong/plower3362/main_intro.png",
alt: "ํฉ์ฒ ๊ณค",
},
{
img: "https://img.megagong.net/profphoto/gong/happy0308/main_intro.png",
alt: "์ด์ํ",
},
{
img: "https://img.megagong.net/profphoto/gong/shin242/main_intro.png",
alt: "์ ์ฉํ",
},
],
},
{
label: "ํ์ ๋ฒ",
slides: [
{
img: "https://img.megagong.net/profphoto/gong/allawyer/main_intro.png",
alt: "์ ํ์ด",
},
{
img: "https://img.megagong.net/profphoto/gong/wjsgywls1/main_intro.png",
alt: "์ ํจ์ง",
},
{
img: "https://img.megagong.net/profphoto/gong/geek2991/main_intro.png",
alt: "์ ์ธ๊ตญ",
},
{
img: "https://img.megagong.net/profphoto/gong/ysw7/main_intro.png",
alt: "์์น์ฐ",
},
],
},
],
};
},
methods: {
changeTab(index) {
this.currentTab = index;
this.mounted = false;
this.$nextTick(() => {
this.renderKey++;
this.mounted = true;
});
},
},
};
</script>
<style scoped lang="scss">
.main-tabs {
width: 790px;
.title {
font-size: 18px;
font-weight: bold;
margin-bottom: 16px;
}
.tab-slide {
.tabs {
display: flex;
gap: 12px;
margin-bottom: 20px;
button {
background: #f2f2f2;
border: none;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
color: #333;
&.active {
background: #0055ff;
color: #fff;
}
}
}
}
}
</style>
๐งฉ 2. TabSlide.vue
๊ตฌํ
Swiper๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ผ์ด๋ ๊ตฌ์ฑํฉ๋๋ค.
<template>
<swiper ref="mySwiper" :options="swiperOption" class="swiper-container">
<swiper-slide v-for="(item, i) in slides" :key="i" class="teacher-slide">
<div class="teacher-box">
<img :src="item.img" :alt="item.alt" />
<p class="teacher-name">{{ item.alt }}</p>
</div>
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</template>
<script>
export default {
props: {
slides: {
type: Array,
required: true,
},
},
data() {
return {
swiperOption: {
slidesPerView: 4,
spaceBetween: 10,
pagination: {
el: ".swiper-pagination",
},
loop: false,
},
};
},
watch: {
slides() {
this.$nextTick(() => {
const swiper = this.$refs.mySwiper?.swiper;
if (swiper) {
swiper.update();
swiper.slideTo(0);
}
});
},
},
};
</script>
<style scoped>
.swiper-container {
width: 100%;
overflow: hidden;
}
.swiper-slide {
/* width: auto !important; */
flex-shrink: 0;
display: flex;
justify-content: center;
}
.teacher-box {
width: 100%;
max-width: 200px;
background: #fff;
border: 1px solid #eee;
border-radius: 8px;
padding: 12px;
text-align: center;
}
.teacher-box:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.teacher-box img {
width: 100%;
height: auto;
border-radius: 4px;
margin-bottom: 8px;
}
.teacher-name {
font-size: 14px;
font-weight: 600;
color: #333;
}
</style>
โ ์คํ ๊ฒฐ๊ณผ
- ์๋จ ํญ์ ํด๋ฆญํ๋ฉด ํด๋นํ๋ ์ฌ๋ผ์ด๋ ์ฝํ ์ธ ๊ฐ ์๋์ผ๋ก ๋ฐ๋๋๋ค.
- ๊ฐ๊ฐ์ ์ฌ๋ผ์ด๋๋ Swiper๋ก ์ฌ๋ผ์ด๋ ์ด๋์ด ๊ฐ๋ฅํฉ๋๋ค.
๐ฏ ๋ค์ ๊ณผ์
์๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํด๋ณด์ธ์!
๊ฐ ์ฌ๋ผ์ด๋ ์์ดํ ์ ๊ณผ๋ชฉ ํ ์คํธ๋ ํจ๊ป ์ถ๋ ฅ
์์:
{ img: "...", alt: "๋ผ์ํ", subject: "ํ๊ตญ์ฌ" }
๋ฐ์ํ ์ฒ๋ฆฌ (768px ์ดํ์์ ์ฌ๋ผ์ด๋ ์ ์ค์ด๊ธฐ)
Swiper ์ต์ ์์
breakpoints
์ค์ ์ถ๊ฐ.
๐ฌ ๋๊ธ
โป ๋ก๊ทธ์ธ ํ ๋๊ธ์ ์์ฑํ ์ ์์ต๋๋ค.