[vue] DarkMode 구현

youngseo·2022년 7월 20일
1

DarkMode 구현

이번에 진행하게 된 그룹과제에 DarkMode를 구현해보고 싶었습니다. darkmode를 처음 시도해보는 일이라 과연 vue로 구현을 할 수 있을까 하는 걱정도 있었지만, 나중에하고 미루기 보다는 이번에는 시간을 내어 꼭 구현을 해보자 마음 먹었습니다!💪

구현 방법

다크모드를 구현하는데는 정말 여러가지 방법이 있지만 이번에는 data-set과 컬러변수를 이용한 방법을 시도해보았습니다.

1. 색깔 변수설정

  body {
  	background-color: var(--color-body);
    color: var(--color-text);
  }

  html[data-theme="lightMode"] {
    --color-body : #fff;
    --color-text: #000;
  }
  html[data-theme="darkMode"] {
    --color-body : #000;
    --color-text: #fff;
  }

위와 같이 사용할 색상변수네이밍을 정한 후 darkmode와 lightmode에서 정의되는 색을 명시합니다.

저의 경우 프로젝트가 어느정도 마무리가 되어가는 과정에서 다크모드를 구현하려다 보니 색상을 하나하나 확인하며 정의해야하는 아쉬움이 있었기에👉👈, 미리 변수화하고 사용을 하는 것을 권장합니다.

왜 SCSS를 사용하지 않고 CSS를?!

사실 data-set과 컬러변수를 이용해 다크모드를 구현해야지 하고 마음을 먹고 scss를 이용해 컬러변수를 도입해보았지만 마음먹은대로 구현이 되지 않아 거의 프로젝트 마무리 단계까지 다크모드를 미뤄놓게 되었었습니다(왜 안되지?!!!)😅

어떤 부분에서 문제가 발생하는지를 정확히 찾지 못했는데 만약 scss를 이용하는 경우 아래와 같이 설정을 해줘야한다고 합니다. (출처)

$colors:(
  light: (
    bg-color:#fff,
    text-color:#323232,
  ),
  dark: (
    bg-color:#323232,
    text-color:#fff,
  )
);


@function get-color($key, $type: 'light'){
  @each $name, $color in map-get($colors, $type){
    @if($key == $name){
      @return $color
    }
  }
}

@mixin get-color($property,$color){
  #{$property}: get-color($color);
  @at-root .wrapper.dark & {
    #{$property}: get-color($color, dark);
  }
}

2. data만들기

<button @click="toggleTheme">
  <span v-if="theme == 'darkMode'">ligtMode</span>
  <span v-else>DarkMode</span>
</button>
  data() {
    return {
      theme:'lightMode'
    }
  }, 

버튼이 클릭 되는 경우 theme이라는 데이터의 값이 변경될 수 있도록 theme데이터의 초기값을 lighthMode로 설정을 해주었습니다.

3. 함수만들기

  methods: {
    toggleTheme() {
      this.theme = this.theme == 'darkMode' ? 'lightMode' : 'darkMode'
      localStorage.setItem('theme', this.theme)
      document.documentElement.setAttribute('data-theme', this.theme) 
    }
  }

버튼이 클릭 되는 경우 theme의 데이터값이 darkmode와 lightmode로 바뀔 수 있도록 설정을 한 후 그 값을 로컬스토로지에 저장을 했습니다. 그런 후 data의 속성을 변경해줍니다.

4. mounted 이용

  mounted() {
    let localTheme = localStorage.getItem('theme')
    document.documentElement.setAttribute('data-theme', localTheme) 
    this.theme = localTheme   
  }

프로젝트가 시작될 때 로컬에 저장되어 있는 theme속성을 가져와 바로 적용될 수 있도록 mounted 이용했습니다.

또한 만약 로컬스토로지에 저장된 값이 없다면 data의 초기 값인 light모드를 적용할 수 있도록 아래와 같이 로직을 작성해주었습니다.

  mounted() {
    let localTheme = localStorage.getItem('theme')
    if(localTheme) {
      document.documentElement.setAttribute('data-theme', localTheme)  
      this.theme = localTheme   
    } else {
      document.documentElement.setAttribute('data-theme', this.theme)
      window.localStorage.setItem('theme', this.theme)
    }
  },

완성본

쨔쟌!

다음 번에는 prefers-color-scheme 를 이용해 한번 도전해보고 싶다.🐥

0개의 댓글