Vue.js 3.0 기본 레이아웃 - (4) Navigation Drawer 슬라이딩 에니메이션

|

Navigation Drawer Slide 애니메이션

기존 코드에서 아래 부분에 애니메이션이 추가되었습니다.

<script setup>
let isDrawerOpened = false;

const toggleDrawer = () => {
  isDrawerOpened = !isDrawerOpened;
  if (isDrawerOpened) {
    document.getElementById("drawer").style.width = "200px";
  } else {
    document.getElementById("drawer").style.width = "0px";
  }
};
</script>

#drawer {
  display: flex;
  flex-direction: column;
  width: 0px;
  height: 100vh;
  background: darkcyan;
  color: white;
  transition: 0.2s;
  overflow-x: hidden;
}

전체 코드

<template>
  <div id="wrapper">
    <!-- Navigation Drawer -->
    <div id="drawer">
      <div id="drawer-header">SnowDeer Drawer</div>
      <div id="drawer-content">
        <div id="drawer-menu-item">
          <i class="bi bi-house"></i>
          <span>Home</span>
        </div>
        <div id="drawer-menu-item">
          <i class="bi bi-gift"></i>
          <span>Hello</span>
        </div>
        <div id="drawer-menu-item">
          <i class="bi bi-info-square"></i>
          <span>About</span>
        </div>
      </div>
    </div>
    <!-- Main -->
    <div id="main">
      <!-- AppBar -->
      <div id="appbar">
        <div id="hamburg-menu" class="h-center v-center" @click="toggleDrawer">
          <i class="bi bi-list"></i>
        </div>
        <div id="title" class="v-center">AppBar Title</div>
        <div id="action-items">
          <i class="action-item bi bi-heart"></i>
          <i class="action-item bi bi-three-dots-vertical"></i>
        </div>
      </div>
      <!-- Content -->
      <div id="content"></div>
    </div>
  </div>
</template>

<script setup>
let isDrawerOpened = false;

const toggleDrawer = () => {
  isDrawerOpened = !isDrawerOpened;
  if (isDrawerOpened) {
    document.getElementById("drawer").style.width = "200px";
  } else {
    document.getElementById("drawer").style.width = "0px";
  }
};
</script>

<style>
.h-center {
  display: flex;
  flex-direction: row;
  justify-content: center;
}

.v-center {
  display: flex;
  flex-direction: row;
  align-items: center;
}

#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#wrapper {
  display: -webkit-flex;
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  width: 100vw;
  height: 100vh;
  margin: 0 auto;
}

#main {
  flex: 1;
  flex-flow: column wrap;
  justify-content: flex-start;
  background: #bbe4e9;
  transition: margin-left 0.5s;
}

#appbar {
  display: flex;
  flex-direction: row;
  height: 48px;
  background: #edb1f1;
}

#hamburg-menu {
  width: 48px;
  height: 48px;
  background: #d59bf6;
  cursor: pointer;
}

#title {
  flex: 1;
  height: 48px;
}

#action-items {
  display: flex;
  flex-direction: row;
  height: 48px;
  background: #d59bf6;
}

.action-item {
  width: 48px;
  height: 48px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
}

#drawer {
  display: flex;
  flex-direction: column;
  width: 0px;
  height: 100vh;
  background: darkcyan;
  color: white;
  transition: 0.2s;
  overflow-x: hidden;
}

#drawer-header {
  width: 100%;
  height: 100px;
  padding: 20px;
  background: teal;
}

#drawer-content {
  flex: 1;
}

#drawer-menu-item {
  padding: 16px;
  cursor: pointer;
}

#drawer-menu-item:hover {
  color: black;
  background: turquoise;
}
</style>