外部モジュールを使うと簡単にできます。
上記方法は SASS/SCSS も動くことを確認しました。
この方法は SASS/SCSS の設定がうまくできませんでした(2023/12 現在, Nuxt 3.8.2 / Vuetify 3.4.6)。うまくいく方法があったら教えてください。
そんなわけで、下記の記事はあまり意味がなくなった気はしますが、参考のために残しておきます。
以下の記事は、外部のモジュールに頼らずに Nuxt3 に Vuetify3 を導入する方法について記述しています。SASS/SCSS についても記述しています。
主旨
理解は後でいいから、とりあえずコピペで動けばOKという場合は、ページ末尾の「全部盛り」を見てください。
npm でなく yarn を使ってます。
windows (not WSL) で実行する場合は、yarn や nuxi などのコマンドは、npx 付きで実行します。
たとえば、
> npx nuxi init app
> cd app
> npx yarn install
こんなかんじです。
準備
linx/windows WSL2/mac os でやります。
$ npm -v
9.6.7
$ node -v
v16.16.0
$ nuxi -v
Nuxi 3.5.3
$ yarn -v
1.22.19
nuxi がない場合はインストールします。
$ sudo npm i -g nuxt@latest
手順
アプリの作成とモジュールのインストール
$ nuxi init nuxt3-vuetify3-stable
$ cd nuxt3-vuetify3-stable/
$ yarn add vuetify@next
$ yarn add sass
$ yarn install
vuetify は @next
とするか、@3.8.0
などとバージョンを指定します。記事を書いている時点では、バージョンを指定しないと vuetify@2.x が入ってしまいます。
vuetify のインストール中にバージョンを選択のリストが出たときは、最新版(2023/11時点では3.4.0)を選びます。
plugins/vuetify.js の追加
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components'
export default defineNuxtPlugin( nuxtApp => {
const vuetify = createVuetify({
components
});
nuxtApp.vueApp.use( vuetify );
});
app.vue の編集
下記ページにある Basic のところにあるコードをそのまま app.vue にコピペします。
<template>
<template>
<v-app>
<v-container>
<v-card
width="400"
title="This is a title"
subtitle="This is a subtitle"
text="This is content"
></v-card>
<div class="mt-4 text-subtitle-2">With slots</div>
<v-card width="400">
<template v-slot:title>
This is a title
</template>
<template v-slot:subtitle>
This is a subtitle
</template>
<template v-slot:text>
This is content
</template>
</v-card>
<div class="mt-4 text-subtitle-2">With markup</div>
<v-card width="400">
<v-card-item>
<v-card-title>This is a title</v-card-title>
<v-card-subtitle>This is a subtitle</v-card-subtitle>
</v-card-item>
<v-card-text>
This is content
</v-card-text>
</v-card>
</v-container>
</v-app>
</template>
nuxt.config.ts の編集
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
css: [
"vuetify/lib/styles/main.sass"
],
build: {
transpile: ["vuetify"]
},
vite: {
define: {
"process.env.DEBUG": false
},
// for HMR
server: {
watch: {
usePolling: true
}
},
}
});
テスト
$ npm run dev
または
$ yarn dev
これで http://localhost:3000/ にブラウザでアクセスして、下記のようなページが表示されたら成功です。
ルーティング機能のテスト
現状の app.vue を pages/index.vue に移動します。
$ mkdir pages
$ mv app.vue pages/index.vue
新たに app.vue を作ります。
<template>
<div>
<NuxtPage />
</div>
</template>
pages/about.vue を下記の内容で作ります。
<template>
<v-container>
<h2>{{ title }}</h2>
<v-btn @click="pushButton">
PUSH!
</v-btn>
</v-container>
</template>
<script>
export default {
data: () => ({
title: "This is the test page."
}),
methods: {
pushButton(){
this.title = "PUSHED!";
}
}
}
</script>
これで yarn dev しなおします。(HMR だけではエラーになる)
http;//localhost:3000 で表示される内容は、pages/index.vue の中身になるはずです。
http;//localhost:3000/about にアクセスすると、下記のページが表示されるはずです。
PUSH を押すと、下記のように変わるはずです。
こんなかんじになれば、正常に動いてます(多分)。
おまけ
mdi-font を使う場合
$ yarn add @mdi/font
としてから、nuxt.config.ts を編集します。
css: [
"vuetify/lib/styles/main.sass",
"@mdi/font/css/materialdesignicons.css"
],
primary/secondary の色を 2.x と同じにする
vuetify3 のデフォルトのテーマ light の primary / secondary の色は下図のようにになります。
2.x のテーマと同じ色にしたければ、plugins/vuetify.js を下記のようにします。
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components'
export default defineNuxtPlugin( nuxtApp => {
const vuetify = createVuetify({
components,
theme: {
themes: {
light: {
colors: {
primary: '#1976D2',
secondary: '#424242',
accent: '#82B1FF',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FFC107',
},
},
},
}
});
nuxtApp.vueApp.use( vuetify );
});
これで、下記のように色が 2.x のデフォルトと同じになります。
Roboto フォントにする
デフォルトでは Roboto フォントが読み込まれないので、2.x とは違うフォントになります。下記は Roboto フォントを使えるようにする方法のひとつです。
webfontloader を使う
$ yarn add webfontloader
plugins/webfontloader.client.js
を作成します。
import webFontLoader from 'webfontloader';
export default defineNuxtPlugin( nuxtApp => {
webFontLoader.load({
google: {
families: ['Roboto:100,300,400,500,700,900&display=swap'],
},
})
});
これで Roboto フォントになります。
@nuxt/google-fonts
でもできそうなのですが、nuxt3 でうまく読み込ませられませんでした。わかる方がいましたら教えてください。
directive
ディレクティブを使う場合は、vuetify.js に追記が必要です。
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
export default defineNuxtPlugin( nuxtApp => {
const vuetify = createVuetify({
components,
directives,
});
nuxtApp.vueApp.use( vuetify );
});
SASS/SCSS を使う
現状 (Nuxt 3.8.2 + Vuetify 3.4.6 の組み合わせで)使うには vite-vuetify-plugin
を追加する必要があります。
$ yarn add vite-plugin-vuetify
nuxt.config.ts
に追記します。
import vuetify from "vite-plugin-vuetify";
export default defineNuxtConfig({
...
css: [
"vuetify/styles"
],
hooks: {
'vite:extendConfig': (config) => {
config.plugins!.push(
vuetify({
autoImport: true,
styles: {
configFile: 'styles/settings.scss',
},
})
);
},
},
}
@use 'vuetify/settings' with (
$button-height: 100px,
);
これで使えるようになります。ただし yarn dev
すると大量のワーニングがコンソールに出力されます。このワーニングは、下記のようにすると一応消すことはできます。
export default defineNuxtConfig({
...
sourcemap: {
client: false,
server: false,
},
ssr: false,
これだと ssr が無効化されてしまうのですが、ssr を有効にすると、どうしてもワーニングが出ることは避けられないようです。ssr を有効化してもワーニングが出るだけで動作自体には問題はないのですが、気持ち悪くはあります。
なお ssr: true
としても yarn build
や yarn generate
ではワーニングはでないので、気にしなければOKなのかもしれません。
一方で、下記のように vue
ファイル内にダイレクトに @use
などを書く方法は、現状うまくいかないようです。
<template>
<v-container class="h-100">
<v-btn>
Test
</v-btn>
</v-container>
</template>
<style lang="scss">
@use 'vuetify/settings' with (
$button-height: 100px,
);
</style>
一応、下記を nuxt.config.ts
に追記し、なおかつ styles/setting.scss
を使わない場合は動くように見えます。しかし styles/setting.scss
との共存はどうしてもうまくいかないようです。
experimental: {
inlineSSRStyles: false
}
こんな感じで SASS/SCSS 周りの動作は怪しいところが多いです。
なお vuetify-nuxt-module
を使うとこのあたりの問題は(ワーニング出る部分以外は)解決しているようです。SASS/SCSS を使うならその選択肢一択かもしれません。
全部盛り
とりあえず Vuetify2 と同じ見た目になれば OK という場合は、下記をコピペすれば幸せになれます(多分)。sass 周りはワーニングが出てしまうので追加してません。必要なら、前述の sass/scss の項目を見て追記してください。
$ nuxi init nuxt3-vuetify3-stable
$ cd nuxt3-vuetify3-stable/
$ yarn add vuetify@next sass @mdi/font webfontloader
export default defineNuxtConfig({
css: [
"vuetify/lib/styles/main.sass",
"@mdi/font/css/materialdesignicons.css"
],
build: {
transpile: ["vuetify"]
},
vite: {
define: {
"process.env.DEBUG": false
},
// for HMR
server: {
watch: {
usePolling: true
}
},
},
})
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
export default defineNuxtPlugin( nuxtApp => {
const vuetify = createVuetify({
components,
directives,
theme: {
themes: {
light: {
colors: {
primary: '#1976D2',
secondary: '#424242',
accent: '#82B1FF',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FFC107',
},
},
},
}
});
nuxtApp.vueApp.use( vuetify );
});
import webFontLoader from 'webfontloader';
export default defineNuxtPlugin( nuxtApp => {
webFontLoader.load({
google: {
families: ['Roboto:100,300,400,500,700,900&display=swap'],
},
})
});
関連記事
つぶやき
nuxt で開発するなら、作業用のディスクは SSD (できれば PCIe) を使うことを強くお勧めします(HDDだと非常に遅いです。