Nuxt 3 で Vuetify 3 を使う
Nuxt 3 で Vuetify 3 を使った開発の始め方をまとめました。
この記事の初稿時点でのバージョンは下記のとおりです。
- Nuxt 3.2.0
- 公式サイト: https://nuxt.com/
- リポジトリ: https://github.com/nuxt/nuxt
- Vuetify 3.1.4
- 公式サイト: https://vuetifyjs.com/
- リポジトリ: https://github.com/vuetifyjs/vuetify
Nuxt 3 をインストールする
Nuxt 3 を始める際は、つぎのコマンドを利用します。
npx nuxi init プロジェクト名 # フォルダ名になります
そして Nuxt 3 と、そのなかで使われている各種パッケージをインストールします。
cd プロジェクト名
npm install # もしくは yarn install, pnpm install など
無事入ったら、開発サーバーを立ち上げると、サンプルのウェルカムページが立ち上がることでしょう。
npm run dev # もしくは yarn dev, pnpm dev など
デフォルトの場合 http://localhost:3000
で開けます。
Nuxt 3.0.0 がリリースされた際にキャプチャした動画です。
Vite の圧倒的な速さが分かりますね。
Vuetify 3 をセットアップする
Vuetify 3 と sass と Vite のプラグインを入れます。
npm install -D vuetify@next sass vite-plugin-vuetify
Nuxt のプラグインで Vuetify を読み込む
いまのところ、公式の Nuxt モジュールが存在しないため、 Nuxt のプラグインとして Vue で Vuetify を使えるようにします。
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
export default defineNuxtPlugin(nuxtApp => {
const vuetify = createVuetify({
ssr: true,
components,
directives,
// 他の設定をここに記述していく
})
// Vue.js で Vuetify を使用する
nuxtApp.vueApp.use(vuetify)
})
createVuetify()
の引数として、各種設定を読み込みます。
このままでも良いですが、別で設定ファイルを用意しておき読み込むようにすると管理しやすくなりますので後述します
nuxt.config.ts
nuxt.config.ts
で Vuetify の事前ビルドと sass ファイルの読み込みを行います。
先立って次のファイルを用意します。
@use "vuetify/styles";
@use "vuetify";
だと、Nuxt 3.1.2 以降でうまく読み込まれないため、直接ファイルを指定しています
@use "vuetify/styles";
に変更されています。
あらためて nuxt.config.ts
を記述します。
なお、上述のプラグインファイルは自動的に読み込まれるため、記載しません。
import { defineNuxtConfig } from 'nuxt/config'
import vuetify from 'vite-plugin-vuetify'
export default defineNuxtConfig({
build: {
transpile: ['vuetify'],
},
hooks: {
'vite:extendConfig': (config) => {
config.plugins!.push(vuetify())
},
},
vite: {
ssr: {
noExternal: ['vuetify'],
},
define: {
'process.env.DEBUG': false,
},
},
css: ['@/assets/main.scss'],
})
ここまでで使えるようになったはずです。
app.vue を書き換えて確認してみてください。
<template>
<div>
<VBtn>Vuetify のボタン</VBtn>
</div>
</template>
Vuetify の設定をカスタマイズしやすいようにする
Vuetify の各コンポーネントのデフォルト設定を行うファイルを作成します。
import { DefaultsInstance } from 'vuetify/lib/framework.mjs'
export const defaults: DefaultsInstance = {
VAppBar: {
elevation: 0,
},
VBtn: {
variant: 'flat',
height: 38,
rounded: 'lg',
size: 'small',
},
VTextField: {
color: 'primary',
variant: 'outlined',
density: 'comfortable',
},
}
設定する内容は好みで構いません
つぎに、テーマファイルを作成します。
import { ThemeDefinition } from 'vuetify'
// テーマ名
export const MAIN_THEME = 'mainTheme'
// Light mode theme
export const mainTheme: ThemeDefinition = {
dark: false,
colors: {
background: '#FFFFFF',
surface: '#FFFFFF',
primary: '#4f46e5',
secondary: '#9333ea',
error: '#ef4444',
info: '#3b82f6',
success: '#22c55e',
warning: '#f59e0b',
},
}
// Dark モードのテーマ名
export const MAIN_DARK_THEME = 'mainDarkTheme'
// Dark mode theme
export const mainDarkTheme: ThemeDefinition = {
dark: true,
colors: {
background: '#0C111B',
surface: '#1f2937',
primary: '#6366f1',
secondary: '#9333ea',
error: '#ef4444',
info: '#3b82f6',
success: '#22c55e',
warning: '#f59e0b',
},
}
これをプラグインで読み込みます。
import { createVuetify } from 'vuetify'
import { MAIN_THEME, mainTheme, MAIN_DARK_THEME, mainDarkTheme } from '@/helpers/themes'
import { defaults } from '@/helpers/defaults'
import '@mdi/font/css/materialdesignicons.css' // 使用するアイコンを読み込む `mdi-xxx`
export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({
ssr: true,
defaults,
display: {
mobileBreakpoint: 'sm',
},
// add theme
theme: {
defaultTheme: MAIN_THEME,
themes: {
mainTheme,
mainDarkTheme,
},
// primary-darken-9 primary-lighten-9 までできるようにする
variations: {
colors: ['primary', 'secondary', 'accent'],
lighten: 9,
darken: 9,
},
},
})
nuxtApp.vueApp.use(vuetify)
})
必要なアイコンのみ読み込むようにする方法
plugins/vuetify.ts
で読み込んでいる @mdi/font/css/materialdesignicons.css
は、すべてのアイコンを読み込んでいるため、ファイルサイズが大きくなります。
手元のバージョンで 394KB ありました。
これを必要なアイコンのみ読み込むように変更する対応です。
こちらの記事に書かれている内容をそのまま実装してみました。
(引き続きMaterial Design Iconsを使用した場合の実装例です)
npm install -D @mdi/js
必要なファイルをインストールしたのち plugins/vuetify.ts
をつぎのように変更します。
import { createVuetify } from 'vuetify'
+ import { aliases, mdi } from 'vuetify/iconsets/mdi-svg'
import { MAIN_THEME, mainTheme, MAIN_DARK_THEME, mainDarkTheme } from '@/helpers/themes'
import { defaults } from '@/helpers/defaults'
- import '@mdi/font/css/materialdesignicons.css' // 使用するアイコンを読み込む `mdi-xxx`
export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({
ssr: true,
defaults,
display: {
mobileBreakpoint: 'sm',
},
+ // add icons
+ icons: {
+ defaultSet: 'mdi',
+ aliases,
+ sets: {
+ mdi,
+ },
+ },
// add theme
theme: {
defaultTheme: MAIN_THEME,
themes: {
mainTheme,
mainDarkTheme,
},
// primary-darken-9 primary-lighten-9 までできるようにする
variations: {
colors: ['primary', 'secondary', 'accent'],
lighten: 9,
darken: 9,
},
},
})
nuxtApp.vueApp.use(vuetify)
})
これで準備は整いました。
各コンポーネントでは利用するアイコンのみを次のように import したうえで利用します。
<script setup lang="ts">
import { mdiPost } from '@mdi/js'
</script>
<template>
<VIcon :icon="mdiPost" />
</template>
これで適切に Tree Shaking され、ビルド後のファイルサイズは削減されます。
おわりに
以上でセットアップ完了です。
Vuetify 3 は ver 2 と比較して、より簡潔に記述できるようになりました。
記述方法の変更もありますので、しばらくは(英語の)公式ドキュメントを読みながら作業する必要がありそうです。
(機会があればまとめたいと思います)
個人的には、全 Vue.js ユーザーにおすすめな UnoCSS と併用して使っています。
(Tailwind CSS 互換のユーティリティクラスを自動的に生成してくれるので便利です)
また Material Design ではないようですが Anu にも注目しています。
(UnoCSS による UI コンポーネントです)
大抵のコンポーネントはすでにひととおり揃っていますので、よりライトに各種 UI を活用できそうですね。
誤記や間違いを見つけた方へ
ぜひコメントでお知らせくださいませ。
より正確な情報を広めていきたいと思っています。
Discussion
plugins/vuetify.ts の
ですが、
createVuetify に
を追加するとステキだと思いました
ここのをパクっただけですが・・・
おお!そんなことができるようになっていたのですねー
試してみて書き換えます!
コメントありがとうございます 🙂
(2023-02-25: 追記しました!ありがとうございます)
とてもわかりやすいです。
Nuxt3でv-deta-tableを実装したいのですが、可能でしょうか。
components:{VDataTable }の記述の仕方ご存知でしたら教えてほしいです。
app.vueのソースですが、
divが閉じていませんでした・・・
ありがとうございますー。修正しました!
下記のインストールするコマンドについて、
npm install -D vuetify@next
通常は最新バージョンである@latestでインストールすると思いますが、
@nextにした理由は何かありますか?
コピペマンがこの記事を参考にした時に苦労するのではないかなって思いました。
ありがとうございます。この記事はちょっと古いです。
記事を書いた当時、そういう状況だったからですね。
いまだと Vuetify Module あると思うのでそれを利用するとよいかと思います。