[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.js
import Vue from "vue"; import Vuex from "vuex"; import ui from "./ui"; Vue.use(Vuex); export default new Vuex.Store({ /** 모듈 등록 */ modules: { ui, }, });

2. 설명