
먼저 다크모드를 사용해보자.
셋팅을 하고 토글버튼을 만든다.
// tailwind.config.js
module.exports = {
...
darkMode: 'class'
...
};
class로 darkMode를 지정해준다.
public/index.html에서 html 태그에 class="dark"가 들어가면 다크모드가 적용된다.
헤더에 토글버튼을 만들어보자.
// Header.vue
<template>
<header class="fixed left-0 right-0 z-30 flex items-center justify-between bg-white dark:bg-gray-900 dark:border-gray-600 topp-0 h-100 border-b-1 ">
<div class="flex items-center">
<button v-if="state.darkMode === 'dark'" @click="onClickDarkMode('light')" id="light" class="p-10 border-none rounded-full dark:hover:bg-gray-700 hover:bg-gray-200">
<img src="~@/assets/images/icon-filter-dark.svg" class="w-30 h-30"/>
</button>
<button v-else @click="onClickDarkMode('dark')" id="dark" class="p-10 border-none rounded-full dark:hover:bg-gray-700 hover:bg-gray-200">
<img src="~@/assets/images/icon-filter-light.svg" class="w-30 h-30"/>
</button>
</div>
</header>
</template>
<script lang="ts">
import { computed, defineComponent, onMounted, reactive } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
export default defineComponent({
components: {
},
setup() {
const store = useStore();
const router = useRouter();
const state = reactive({
darkMode: computed(() => store.getters['utils/mode']),
});
onMounted(() => {
});
const onClickDarkMode = (id:string) => {
const root = document.querySelector('html');
if(id === 'dark'){
root!.classList.add('dark');
window.localStorage.setItem('mode', 'dark');
store.dispatch('utils/mode', 'dark');
} else if(id === 'light'){
root!.classList.remove('dark');
window.localStorage.setItem('mode', 'light');
store.dispatch('utils/mode', 'light');
};
};
return {
state,
onMounted,
onClickDarkMode,
};
},
});
</script>
사용자의 모드 설정을 무기한 저장하기 위해 세션스토리지를, 전역변수로 활용하기 위해 스토어를 사용했다.
토글버튼을 누르면 html 태그에 dark 클래스를 추가할지 삭제할지 구현했다.
이제 저장한 스토리지와 스토어를 활용하여 페이지가 로딩될 때를 처리해보자.
// App.vue
<script lang="ts">
import { computed, defineComponent, reactive, onMounted } from "vue";
import { useStore } from "vuex";
import ModalArea from "./ModalArea.vue";
export default defineComponent({
components: {
ModalArea,
},
setup() {
const store = useStore();
const state = reactive({
darkMode: computed(() => store.getters["utils/mode"]),
})
onMounted(() => {
const root = document.querySelector('html');
const userDefaultMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
if(userDefaultMode){
store.dispatch('utils/mode', 'dark');
root!.classList.add('dark');
};
const mode = window.localStorage.getItem('mode');
if(mode){
store.dispatch('utils/mode', mode);
}
if(state.darkMode === 'dark'){
root!.classList.add('dark');
} else {
root!.classList.remove('dark');
};
});
return {
onMounted,
};
},
});
</script>
루트 페이지인 App.vue에서 전역으로 발동시켰다.
중간에 prefers-color-schme는 유저가 시스템을 다크모드로 설정해놓았다면 이를 체크하고 자동으로 다크모드로 변환해주는 코드를 구현했다.
그럼 이제 다크모드를 적용해보자.
<template>
<aside class="fixed left-0 z-10 h-screen bg-white dark:text-gray-200 dark:bg-gray-900 w-300 border-r-1 dark:border-gray-600">
<div class="flex flex-col px-20 py-10 mt-130">
<router-link @click="onClickMenu('dashboard')" class="flex items-center p-8 rounded-md text-lgdark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700" to="/discover">
<img v-if="state.darkMode === 'dark'" src="~@/assets/images/icon_home_dark.svg" class="mr-20"/>
<img v-else src="~@/assets/images/icon_home_light.svg" class="mr-20"/>
<span class="dark:text-gray-200">Dashboard</span>
</router-link>
</div>
</aside>
</template>
class에 동일하게 css를 작성하면 되는데, 다크모드에서 적용할 항목들은 pre-fix로 dark:를 달아주면 된다.
만약 이미지나 다른 컴포넌트를 보여주고 싶다면 state에 현재 모드 store를 불러오고 이를 활용하여 v-if로 구분지었다.
'Client > VueJS 3.0' 카테고리의 다른 글
Tailwindcss) customizing - jit, px (0) | 2022.08.02 |
---|---|
Css) Video tag autoplay가 안될 때 (0) | 2022.07.28 |
Vue3) Youtube iframe 영상 재생 (0) | 2022.07.12 |
Vue3) Tailwind css 적용하기 (0) | 2022.07.11 |
CSS) Box Shadow (0) | 2022.07.07 |