[Vuex] Slide menu (vuex store + vue transition)
[Vuex] Slide menu (vuex store + vue transition)
접었다 펼 수 있는 slide menu를 구현합니다.

- 메뉴의 상태 정보를 관리하기 위해서 Vuex 플러그인을 사용합니다.
- vue transition을 사용해서 메뉴에 슬라이딩 효과를 적용합니다.
Section 1에서는 소스코드를 첨부합니다.
Section 2에서는 코드에 대해 설명합니다.
1. 소스 코드
프로젝트 구조[PROJECT_ROOT]
+- public
| +- index.html
|
+- src
| +- App.vue (E)
| +- main.js
| +- components
| | +- Content.vue (+)
| | +- SlideMenu.vue (+)
| |
| +- store
| +- index.js
| +- ui.js (+)
|
+- package.json
- SlideMenu.vue - 접었다 펼 수 있는 메뉴
- Content.vue - 테스트를 위해서 이곳에 버튼을 추가한 후 메뉴를 접고 펴는 기능을 넣음
- App.vue - 기본 구현을 걷어내고 SlideMenu와 Content를 나란히 배치함
- store/ui.js - 메뉴의 상태(접힘, 펼침)를 관리하기 위한 vuex 모듈
- store/index.js - ui 모듈을 vuex store에 등록합니다.
App.vue<template>
<div id="app">
<transition name="sliding">
<SlideMenu v-if="menuVisible" />
</transition>
<Content />
</div>
</template>
<script>
import SlideMenu from "./components/SlideMenu.vue";
import Content from "./components/Content.vue";
export default {
name: "App",
components: {
SlideMenu,
Content,
},
computed: {
menuVisible() {
return this.$store.state.ui.leftMenu.visible;
},
},
mounted() {
console.log("[STORE] ", this.$store);
// $store.state.ui.leftMenu.visible
},
};
</script>
<style lang="scss">
html,
body {
height: 100%;
}
body {
margin: 0;
padding: 0;
}
#app {
height: 100%;
display: flex;
}
.sliding {
&-enter {
transform: translateX(-100%);
}
&-enter-active {
transition: transform 0.2s ease;
}
&-enter-to {
transform: translateY(0%);
}
&-leave {
transform: translateY(0%);
}
&-leave-active {
transition: transform 0.2s ease;
}
&-leave-to {
transform: translateX(-100%);
}
}
</style>
SlideMenu.vue<template>
<div class="slide-menu">
<h3>Slide Menu</h3>
</div>
</template>
<script>
export default {};
</script>
<style lang="scss" scoped>
.slide-menu {
background-color: aliceblue;
width: 240px;
flex: 0 0 auto;
}
</style>
Content.vue<template>
<div class="content-wrapper">
<h3>content area</h3>
<button v-if="menuVisible" @click="showMenu(false)">HIDE</button>
<button v-else @click="showMenu(true)">SHOW</button>
</div>
</template>
<script>
export default {
mounted() {
console.log("[menu visible?]", this.$store.state.ui.leftMenu.visible);
},
computed: {
menuVisible() {
return this.$store.state.ui.leftMenu.visible;
},
},
methods: {
showMenu(visible) {
this.$store.state.ui.leftMenu.visible = visible;
},
},
};
</script>
<style lang="scss" scoped>
.content-wrapper {
height: 100%;
flex: 1 1 auto;
}
</style>
store/ui.js/**
* ui 담당 모듈(메뉴, 테마 등..)
*/
export default {
state: () => ({
leftMenu: {
visible: true, // 왼쪽 메뉴 상태
},
}),
};
store/index.jsimport Vue from "vue";
import Vuex from "vuex";
import ui from "./ui";
Vue.use(Vuex);
export default new Vuex.Store({
/** 모듈 등록 */
modules: {
ui,
},
});