【Vuetify】 테마 설정에 따라 스타일 변경

14495 단어 Vue.jsvuetifyjsVuetify
Vuetify를 사용하여 View를 조립하면 자체 구성 요소에서도 테마를 설정할 수 있습니다.
그런 때의 Tips입니다.

Vuetify의 테마란?



Vuetify에서는 라이트 다크 테마 설정을 할 수 있습니다.
테마에 따른 스타일이 전체에 적용되므로 플래그 하나로 애플리케이션 전체의 테마를 전환할 수 있습니다.
Application theming — Vuetify.js

또한 앱 레벨뿐만 아니라 각 구성 요소에서도 개별 테마를 설정할 수 있습니다.
예를 들어, 전체에서는 라이트 테마이지만, 일부의 카드만은 다크 테마로 하고 싶다고 할 수 있습니다.
v-app(light)
  ...
    v-card(dark)
      v-card-text 
        // ここはダーク

테마를 설정할 수 있는 컴퍼넌트는, 스스로 설정되어 있으면 그것을 이용합니다만, 아무것도 설정되어 있지 않은 경우는 가까운 부모의 테마가 계승됩니다.
v-card(light)
  // ここはライト
  v-card(dark)
    // ここはダーク
    v-card
      // ここは近い親のを引き継ぐのでダーク

이 가운데, 자작의 컴퍼넌트도 테마에 따라 스타일을 바꾸는 것은 어떻게 하면 좋을까요.

Vuetify의 소스를 바라보기



먼저 어떤 식으로 실현되고 있는지 Vuetify의 소스를 살펴 보겠습니다.
테마의 처리는, Themeable 라고 하는 믹스 인이 사치고 있습니다.
htps : // 기주 b. 코 m/ゔ에치 fyjs/ゔ에치 fy/bぉb/마s테 r/파카게 s/ゔ에치 fy/src/미안 s/테아메아 bぇ/그리고 x. ts
Themeable 그럼 이런 일을 해줍니다.

테마 받기


props 에서 테마를 받을 수 있습니다.
  props: {
    dark: {
      type: Boolean,
      default: null
    } as PropValidator<boolean | null>,
    light: {
      type: Boolean,
      default: null
    } as PropValidator<boolean | null>
  },

조상의 어느 곳에서나 provided되는 테마의 수령



(갑자기 조금 어렵지만...)
조상의 어느 곳에서나 제공되는 테마를 inject 기능을 사용해 받습니다.
어디에서도 제공되지 않는 경우는 디폴트로 라이트 테마입니다.
  inject: {
    theme: {
      default: {
        isDark: false
      }
    }
  },

현재 테마 결정


computed 속성에서 현재 테마를 결정합니다.props 로 건네받는 것이 최우선으로, 지정이 없으면 조상으로부터 provide 된 값을 이용합니다.
  computed: {
    isDark (): boolean {
      if (this.dark === true) {
        // explicitly dark
        return true
      } else if (this.light === true) {
        // explicitly light
        return false
      } else {
        // inherit from parent, or default false if there is none
        return this.theme.isDark
      }
    },
    // ...

판정한 테마를 자손에게 제공



위의 isDarkwatch 하고 믹스 인 내부에 있는 themeableProvide 라는 객체에 설정합니다.
  watch: {
    isDark: {
      handler (newVal, oldVal) {
        if (newVal !== oldVal) {
          this.themeableProvide.isDark = this.isDark
        }
      },
      immediate: true
    }
  }

themeableProvide 를 자손을 향해 provide 합니다.
 provide (): object {
    return {
      theme: this.themeableProvide
    }
  },

provide/inject는?



갑자기 나왔지만 provideinject는 Vue.js 2.2에서 추가 된 기능입니다.

이 옵션 세트는 구성 요소의 계층 구조가 얼마나 깊은지에 관계없이 동일한 상위 체인에있는 한 조상 구성 요소가 모든 하위 구성 요소에 대한 종속 객체의 주입 역할을 할 수있게합니다. 에 사용됩니다. React 에 익숙한 사람들은 React 컨텍스트의 특징과 매우 유사하다고 생각하면 좋을 것입니다.


이 기능을 사용해 각 컴퍼넌트는 부모의 테마를 받고, 자신의 테마를 결정하고 있는군요.

자작 컴포넌트에서 비슷한 일을하는 방법?



자작의 컴퍼넌트에서도 같은 것을 하고 싶다면, Vuetify의 컴퍼넌트로부터 건네받는 테마를 받아 버리면 좋을 것 같네요.
즉, Vuetify의 Themeable 를 이용하거나 Themeable 상당한 것을 자작하여 provide 되고 있는 것을 받으세요.

덧붙여서 TypeScript로 vue-mixin-decoratorvue-property-decorator 를 사용하는 경우는 이런 느낌으로 쓸 수 있습니다.
( provide 찢어져 있습니다 )
import Vue from 'vue';
import { Mixin } from 'vue-mixin-decorator';
import { Prop, Inject } from 'vue-property-decorator';

interface Theme {
    isDark: boolean;
}

@Mixin
export default class Themeable extends Vue {
    @Inject({ from: 'theme', default: { isDark: false } }) theme: Theme;
    @Prop() dark: string;
    @Prop() light: string;

    get isDark() {
        if (this.dark) {
            return true;
        }
        if (this.light) {
            return false;
        }
        return this.theme.isDark;
    }

    get themeClasses() {
        return {
            'theme--dark': this.isDark,
            'theme--light': !this.isDark,
        };
    }
}

사용할 때는 여기.
<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import { Prop } from 'vue-property-decorator';
import { Mixins } from 'vue-mixin-decorator';

import Themeable from '../../mixins/Themeable';

@Component
export default class extends Mixins<Themeable>(Themeable) {
  // 略
}
</script>

<template lang="pug">
div.hogehoge(:class="themeClasses")
  // 略
</template>

<style lang="stylus" scoped>
.hogehoge
  // ライトテーマのスタイル
  color: #000

  &.theme--dark
    // ダークテーマのスタイル
    color: #fff;
</style>

그럼 좋은 Vuetify 생활을! ! !

ps.
Vuetify의 기여 활동이 시작되었습니다

좋은 웹페이지 즐겨찾기