Featured image of post Nuxt 3にVuetify 3を追加した後の細かい設定のメモ

Nuxt 3にVuetify 3を追加した後の細かい設定のメモ

この記事は最終更新日から1年以上経過しています。

これはなに Link to this heading

Nuxt 3にVuetify 3を導入した後に設定した、細かい設定のメモ。

Vuetify自体の導入については、以下の記事を参照のこと。

変更前のVuetifyの設定 Link to this heading

Vuetifyのコンポーネントとdirectivesを読み込み、Material Design Iconsのうち必要なアイコンだけをインポートする設定をしている。

plugins/vuetify.ts
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg';

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    ssr: true,
    components,
    directives,
    icons: {
      defaultSet: 'mdi',
      aliases,
      sets: {
        mdi,
      },
    },
  });

  nuxtApp.vueApp.use(vuetify);
});

blueprintを指定 Link to this heading

Vuetifyはマテリアルデザインに準拠している。マテリアルデザインは、2014年にMaterial Designが定義されたのち、2017年にMaterial Design 2へ仕様が変更され、2022年にはMaterial Design 3が登場した。Vuetifyでは、これらのデザインの仕様のうちどれを利用するかを、blueprintというconfigで変更できる。たとえば、Material Design 3を利用する場合は、以下のようにmd3を指定する。

plugins/vuetify.ts
import { md3 } from 'vuetify/blueprints';

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    blueprint: md3,
  });
});

blueprintの指定によってどのようにデザインが変わるかに関する詳細は、以下のリンクを参照してほしい。

テーマの色を変更 Link to this heading

カラーテーマを変更 Link to this heading

カラーテーマの色を変更する。公式のやり方に準じる。

まず、任意のディレクトリにtheme.tsを作成する。 theme.tsにテーマを以下のように定義する。

theme.ts
import { ThemeDefinition } from 'vuetify';

// #689F38
export const lightTheme: ThemeDefinition = {
  dark: false,
  colors: {
    background: '#fdfdf5',
    surface: '#fdfdf5',
    primary: '#386b01',
    secondary: '#57624a',
    success: '#386664',
    warning: '#ffdad6',
    error: '#ba1a1a',
    info: '#bbece9',
    'on-background': '#1a1c18',
    'on-surface': '#1a1c18',
    'on-primary': '#ffffff',
    'on-secondary': '#ffffff',
    'on-success': '#ffffff',
    'on-warning': '#410002',
    'on-error': '#ffffff',
    'on-info': '#00201f',
  },
};

export const darkTheme: ThemeDefinition = {
  dark: true,
  colors: {
    background: '#1a1c18',
    surface: '#1a1c18',
    primary: '#9cd769',
    secondary: '#becbae',
    success: '#a0cfcd',
    warning: '#93000a',
    error: '#ffb4ab',
    info: '#1e4e4d',
    'on-background': '#e3e3dc',
    'on-surface': '#e3e3dc',
    'on-primary': '#1a3700',
    'on-secondary': '#29341f',
    'on-success': '#003736',
    'on-warning': '#ffdad6',
    'on-error': '#690005',
    'on-info': '#bbece9',
  },
};

上で示したコードの色のkey(backgroundとかsurfaceとか)はThemeDefinitionで定義されているもので、Vuetifyのコンポーネントで自動的に利用される。なお、すべての色を定義する必要はないし、ThemeDefinitionで定義されているkeyのほかに任意のkeyも設定できる。

ちなみに、テーマの色決めには以下のサイトが有用である。

テーマを定義したら、それを利用するために、定義したテーマをcreateVuetifyに渡す。

plugins/vuetify.ts
import { createVuetify } from 'vuetify';

import { lightTheme, darkTheme } from '@/helpers/vuetify/themes';

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    defaultTheme: 'light',
    theme: {
      themes: { light: lightTheme, dark: darkTheme },
    },
  });
});

このテーマをアプリ全体に適用するには、theme.global.name.valueの値を設定したテーマ名(上記の場合はlightdark)に変更する。例を下記に示す。

app.vue
<script setup lang="ts">
import { useTheme } from 'vuetify';
import { mdiWeatherNight, mdiWeatherSunny } from '@mdi/js';

// params
const theme = useTheme();
const themeIcon = computed(
  () => theme.global.current.value.dark
    ? mdiWeatherNight
    : mdiWeatherSunny,
);

// functions
const toggleTheme = () => {
  theme.global.name.value = theme.global.current.value.dark ? 'light' : 'dark';
};
</script>

<template>
  <v-app>
    <v-main>
      <v-container>
        <v-btn :icon="themeIcon" @click="toggleTheme()" />
      </v-container>
    </v-main>
  </v-app>
</template>

上記のコードを実行すると、ボタンクリックでテーマを変更できる。

また、テーマは特定のコンポーネントだけにも適用できる。たとえば以下のようにv-btntheme"light"を指定すると、そのボタンには常に"light"テーマが適用される。

<v-btn theme="light">
  TEST
</v-btn>

この書き方だと常に"light"テーマが適用されるため、theme.global.name.valueの変更の影響を受けなくなる。

Validationを定義 Link to this heading

Vuetifyのカラーシステムを利用すると、テーマの色に対して、色のバリエーションを任意の数生成できる。

たとえば、以下のように書くと、primarysecondarysuccessのそれぞれの色に対して、6つのlightenと3つのdarkenのValidationが定義される。

plugins/vuetify.ts
import { createVuetify } from 'vuetify';

import { lightTheme, darkTheme } from '@/helpers/vuetify/themes';

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    theme: {
      defaultTheme: 'light',
      variations: {
        colors: ['primary', 'secondary', 'success'],
        lighten: 6,
        darken: 3,
      },
      themes: {
        light: lightTheme,
        dark: darkTheme,
      },
    },
  });
});

生成したValidationはclassで利用できる。 たとえば、以下のようにボタンを定義すると、それぞれ色が変わる。

index.vue
<template>
  <div>
    <div class="mb-5">
      <v-btn class="mr-3 bg-primary-lighten-6" text="test" />
      <v-btn class="mr-3 bg-primary-lighten-5" text="test" />
      <v-btn class="mr-3 bg-primary-lighten-4" text="test" />
      <v-btn class="mr-3 bg-primary-lighten-3" text="test" />
      <v-btn class="mr-3 bg-primary-lighten-2" text="test" />
      <v-btn class="mr-3 bg-primary-lighten-1" text="test" />
      <v-btn class="mr-3 bg-primary" text="test" />
      <v-btn class="mr-3 bg-primary-darken-1" text="test" />
      <v-btn class="mr-3 bg-primary-darken-2" text="test" />
      <v-btn class="mr-3 bg-primary-darken-3" text="test" />
    </div>

    <div class="mb-5">
      <v-btn class="mr-3 bg-secondary-lighten-6" text="test" />
      <v-btn class="mr-3 bg-secondary-lighten-5" text="test" />
      <v-btn class="mr-3 bg-secondary-lighten-4" text="test" />
      <v-btn class="mr-3 bg-secondary-lighten-3" text="test" />
      <v-btn class="mr-3 bg-secondary-lighten-2" text="test" />
      <v-btn class="mr-3 bg-secondary-lighten-1" text="test" />
      <v-btn class="mr-3 bg-secondary" text="test" />
      <v-btn class="mr-3 bg-secondary-darken-1" text="test" />
      <v-btn class="mr-3 bg-secondary-darken-2" text="test" />
      <v-btn class="mr-3 bg-secondary-darken-3" text="test" />
    </div>

    <div class="mb-5">
      <template v-for="n in 6" :key="n">
        <v-btn :class="'mr-3 bg-success-lighten-'+(7-n)" text="test" />
      </template>
      <v-btn class="mr-3 bg-success" text="test" />
      <template v-for="n in 3" :key="n">
        <v-btn :class="'mr-3 bg-success-darken-'+n" text="test" />
      </template>
    </div>
  </div>
</template>

Validation buttons

Vuetifyのコンポーネントのカスタマイズファイルを作成 Link to this heading

Vuetifyのコンポーネントは、個々の属性を付与することでスタイルを変更できる。このスタイルをコンポーネントごとに一括で変更できるようにする。

まず、Vuetifyのコンポーネントのデフォルトを設定するファイルを作成する。今回はdefaults.tsという名前で作成した。次に、そこにデフォルトの設定を書き込む。設定の例を以下に示す。

defaults.ts
import { DefaultsInstance } from 'vuetify/lib/framework.mjs';

export const defaults: DefaultsInstance = {
  VBtn: { density: 'compact', elevation: 1 },
};

そして、作成した設定をcreateVuetifyに渡して読み込む。

plugins/vuetify.ts
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';

import { defaults } from '@/helpers/vuetify/defaults';

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    components,
    directives,
    defaults,
  });
});

これにより、Vuetifyのコンポーネントに一括で設定を付与できる。

VBtnの設定が一括で付与されたようす

最終的なVuetifyの設定 Link to this heading

最後に、設定ファイル全体を示しておく。

plugins/vuetify.ts
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg';
import { md3 } from 'vuetify/blueprints';

import { lightTheme, darkTheme } from '@/helpers/vuetify/themes';
import { defaults } from '@/helpers/vuetify/defaults';

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    ssr: true,
    blueprint: md3,
    components,
    directives,
    defaults,
    icons: {
      defaultSet: 'mdi',
      aliases,
      sets: {
        mdi,
      },
    },
    theme: {
      defaultTheme: 'light',
      variations: {
        colors: ['primary', 'secondary', 'success'],
        lighten: 6,
        darken: 3,
      },
      themes: {
        light: lightTheme,
        dark: darkTheme,
      },
    },
  });

  nuxtApp.vueApp.use(vuetify);
});

参考文献・URL Link to this heading

Licensed under CC BY-NC-SA 4.0
最終更新 2月 24, 2025
Hugo で構築されています。
テーマ StackJimmy によって設計されています。