다크모드 구현하기
ㆍProject Diary/Vue (Roblox WebSite)
Vue.js와 Vuex를 사용하여 다크모드를 구현하는 방법 기록
다크모드는 사용자가 웹사이트나 애플리케이션을 어두운 테마로 전환할 수 있는 기능입니다. 이를 통해 시각적 피로를 줄이고, 다양한 환경에서의 가독성을 향상시킬 수 있습니다.
1. Vuex 설정
먼저, 다크모드 상태를 관리하기 위해 Vuex를 설정합니다. Vuex는 Vue.js 애플리케이션에서 상태 관리를 효율적으로 할 수 있게 해주는 라이브러리입니다.
Vuex 설정 (store/index.js 및 store/dark/index.js)
store/index.js
import Vue from "vue";
import Vuex from "vuex";
import VuexPersistence from "vuex-persist";
import modDark from "@/store/dark"; // 다크모드 모듈 추가
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
modDark, // 다크모드 모듈 추가
},
plugins: [new VuexPersistence({ storage: window.localStorage }).plugin],
});
store/dark/index.js
export default {
state: {
dark: false, // 다크모드 초기 상태
},
mutations: {
on__ChangeDark(state) {
state.dark = !state.dark; // 다크모드 상태 변경
},
},
getters: {
fnGetDark(state) {
return state.dark; // 다크모드 상태 반환
},
},
};
2. 다크모드 스타일 설정
다음으로, 다크모드와 관련된 스타일을 설정합니다. 다크모드일 때와 아닐 때의 배경색과 텍스트 색상을 지정합니다.
style.css
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
.dark {
background: radial-gradient(circle, #dfdfdf 1px, transparent 1px), white;
background-position: 0 0, 25px 25px;
background-size: 2rem 2rem;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
}
3. 다크모드 토글 버튼 구현
다음으로, 다크모드를 토글할 수 있는 버튼을 구현합니다. 이 버튼을 클릭하면 Vuex를 통해 다크모드 상태가 변경됩니다.
Header.vue
<template>
<header id="header">
<nav id="header__nav">
<h1 class="header__logo">
<router-link to="/"><img :src="imgUrl" alt="roblox logo" /></router-link>
</h1>
<ul class="header__menuBar">
<li>
<p class="dark dark__mode" :class="{ light: changeDarkMode }" @click="onOff">
<i class="fa-solid fa-moon"></i>
<span>{{ $t("[3].darkmode") }}</span>
</p>
</li>
</ul>
</nav>
</header>
</template>
<script>
export default {
name: "Header",
data() {
return {
imgUrl: "./assets/images/roblox_logo_white_new.svg",
};
},
methods: {
onOff() {
this.$store.commit("on__ChangeDark"); // 다크모드 상태 변경
},
},
computed: {
changeDarkMode() {
return this.$store.getters.fnGetDark; // 다크모드 상태 가져오기
},
},
};
</script>
<style scoped>
.header__menuBar .dark {
//생략
.header__menuBar .light {
//생략
}
</style>
- 다크모드 상태 변경 : onOff 메소드에서 this.$store.commit("on__ChangeDark")를 호출하여 다크모드 상태를 변경합니다.
- 다크모드 상태 가져오기 : changeDarkMode 계산된 속성에서 Vuex 게터를 통해 다크모드 상태를 가져옵니다.
- 다크모드 상태 적용 : 이제 다크모드 상태를 기반으로 스타일을 적용합니다. 각 컴포넌트에서 다크모드 상태에 따라 스타일을 변경할 수 있습니다.
App.vue
<template>
<div :class="{ dark: changeDarkMode }">
<Header class="header"></Header>
<div id="app__contents">
<router-view></router-view>
</div>
<Footer></Footer>
</div>
</template>
<script>
import Header from "./components/layout/Header.vue";
import Footer from "./components/layout/Footer.vue";
export default {
name: "App",
components: {
Header,
Footer,
},
computed: {
changeDarkMode() {
return this.$store.getters.fnGetDark; // 다크모드 상태 가져오기
},
},
};
</script>
<style scoped>
#app__contents {
padding-top: 165px;
}
.dark {
background: radial-gradient(circle, #dfdfdf 1px, transparent 1px), white;
background-position: 0 0, 25px 25px;
background-size: 2rem 2rem;
}
</style>
- 다크모드 상태 기반 스타일 적용: :class="{ dark: changeDarkMode }"를 사용하여 다크모드 상태에 따라 클래스를 적용합니다.
- 계산된 속성 사용: changeDarkMode 계산된 속성에서 Vuex 게터를 통해 다크모드 상태를 가져와서 스타일을 변경합니다.
이로써 Vue.js와 Vuex를 사용하여 다크모드를 구현하는 방법을 살펴보았습니다. 다크모드 상태를 Vuex로 관리하고, 각 컴포넌트에서 이를 기반으로 스타일을 동적으로 변경하여 사용자에게 더 나은 시각적 경험을 제공할 수 있습니다.