๐งฉ ๊ฐ์ ๋ชฉํ
- ๋ฉ์ธ ํ์ด์ง์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ Vuex์์ ์ค์ ๊ด๋ฆฌํ๋๋ก ๋ฆฌํฉํ ๋ง
- ๊ธฐ์กด
axios
์์ฒญ โ Vuex์์ fetch โ ์ปดํฌ๋ํธ์์๋mapState
๋ฐmapActions
์ผ๋ก ์ฌ์ฉ
๐ 1. Vuex ์ค์น ๋ฐ store ๊ตฌ์ฑ
โ ์ค์น
npm install vuex
โก src/store/index.js ์์ฑ
import Vue from 'vue';
import Vuex from 'vuex';
import main from './modules/main';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
main,
},
});
โข src/store/modules/main.js ์์ฑ
import axios from '@/libs/axios';
export default {
namespaced: true,
state: {
mainSlides: [],
mainTabs: [],
promoList: [],
},
mutations: {
setMainSlides(state, slides) {
state.mainSlides = slides;
},
setMainTabs(state, tabs) {
state.mainTabs = tabs;
},
setPromoList(state, list) {
state.promoList = list;
},
},
actions: {
async fetchMainSlides({ commit }) {
const res = await axios.get('/api/main-slides');
commit('setMainSlides', res.data);
},
async fetchMainTabs({ commit }) {
const res = await axios.get('/api/main-tabs');
commit('setMainTabs', res.data);
},
async fetchPromoList({ commit }) {
const res = await axios.get('/api/promo-list');
commit('setPromoList', res.data);
},
},
};
๐ 2. main.js์ store ๋ฑ๋ก
์ด๋ฏธ ๋์ด์๋ ๊ฒฝ์ฐ ํจ์ค
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import VueAwesomeSwiper from "vue-awesome-swiper";
import "swiper/css/swiper.css"; // swiper 5์ฉ css
import "./assets/base.scss";
Vue.use(VueAwesomeSwiper);
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
๐งฉ 3. MainSlide.vue์์ Vuex ์ฐ๋
<script>
import { mapState, mapActions } from 'vuex';
export default {
name: "MainSlide",
computed: {
...mapState('main', ['mainSlides']),
},
created() {
this.fetchMainSlides();
},
methods: {
...mapActions('main', ['fetchMainSlides']),
},
};
</script>
๐งฉ 4. MainTabs.vue์์ Vuex ์ฐ๋
<template>
<div class="main-tabs">
<h3 class="title">๋ฅ์คํธ๊ณต๋ฌด์ 1์ ๊ฐ์ฌ์ง</h3>
<div class="tab-slide">
<div class="tabs">
<button
v-for="(tab, idx) in mainTabs"
:key="idx"
:class="{ active: currentTab === idx }"
@click="changeTab(idx)"
>
{{ tab.label }}
</button>
</div>
<TabSlide
v-if="mounted && mainTabs.length"
:key="renderKey"
:slides="mainTabs[currentTab].slides"
/>
</div>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
import TabSlide from "./TabSlide.vue";
export default {
components: { TabSlide },
data() {
return {
currentTab: 0,
renderKey: 0,
mounted: true,
};
},
computed: {
...mapState('main', ['mainTabs']),
},
created() {
this.fetchMainTabs();
},
methods: {
...mapActions('main', ['fetchMainTabs']),
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>
๐งฉ 5. TeacherPromoSection.vue์์ Vuex ์ฐ๋
<template>
<section class="teacher-promo-section">
<h3 class="section-title">์ง๊ธ ์ฃผ๋ชฉํ ์ ์๋ ๊ธฐํ์ </h3>
<div class="grid">
<TeacherPromoCard v-for="(card, i) in promoList" :key="i" v-bind="card" />
</div>
</section>
</template>
<script>
import { mapState, mapActions } from 'vuex';
import TeacherPromoCard from "./TeacherPromoCard.vue";
export default {
components: { TeacherPromoCard },
computed: {
...mapState('main', ['promoList']),
},
created() {
this.fetchPromoList();
},
methods: {
...mapActions('main', ['fetchPromoList']),
},
};
</script>
<style scoped>
.teacher-promo-section {
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>
GitHub - heroyooi/vue2-megagong at ch9
๐ฏ ๊ณผ์
StickyPanel.vue
์ปดํฌ๋ํธ์ ๋ฐฐ๋ ๋ฐ์ดํฐ๋ฅผ JSON ํ์ผ์์ ๊ฐ์ ธ์ Express API โ Axios โ Vuex๋ก ์ํ ๊ด๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ์ธ์.- ์ค์ ์ถ๋ ฅ๋๋ ์ด๋ฏธ์ง 2~3๊ฐ๋ก ํ ์คํธํ๊ณ , ์๋ฒ/ํ๋ก ํธ ๋ ๋ค ์ ์ ์๋ํ๋์ง ํ์ธํ์ธ์.
๐ฌ ๋๊ธ
โป ๋ก๊ทธ์ธ ํ ๋๊ธ์ ์์ฑํ ์ ์์ต๋๋ค.