在 Nuxt 3.12 使用 Vuetify UI 框架

做法

建立專案。

1
2
npx nuxi init nuxt-app
cd nuxt-app

安裝依賴套件。

1
npm i

安裝 Vuetify 框架和 MDI 字型。

1
npm i vuetify vite-plugin-vuetify

安裝 Sass 預處理器。

1
npm i sass -D

修改 nuxt.config.js 檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify';

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-04-03',
devtools: { enabled: true },
build: {
transpile: ['vuetify'],
},
modules: [
'@nuxt/eslint',
(_options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) => {
// @ts-expect-error
config.plugins.push(vuetify({ autoImport: true }));
});
},
],
vite: {
vue: {
template: {
transformAssetUrls,
},
},
},
});

新增 plugins/vuetify.js 檔。

1
2
3
4
5
6
7
8
9
10
11
import '@mdi/font/css/materialdesignicons.css';
import { defineNuxtPlugin } from 'nuxt/app';
import { createVuetify } from 'vuetify';
import 'vuetify/styles';

export default defineNuxtPlugin((app) => {
const vuetify = createVuetify({
//
});
app.vueApp.use(vuetify);
});

修改 eslint.config.js 檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { createConfigForNuxt } from '@nuxt/eslint-config/flat';

export default createConfigForNuxt({
features: {
stylistic: {
braceStyle: '1tbs',
semi: true,
},
},
})
.override('nuxt/typescript/rules', {
rules: {
'@typescript-eslint/ban-ts-comment': 0,
},
});

新增 layouts/default.vue 檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<v-app>
<v-layout>
<v-app-bar
color="grey"
:height="48"
flat
/>
<ClientOnly>
<v-navigation-drawer
color="grey-lighten-1"
:width="240"
/>
</ClientOnly>
<ClientOnly>
<v-navigation-drawer
color="grey-lighten-2"
:width="240"
/>
</ClientOnly>
<v-main>
<NuxtPage />
</v-main>
</v-layout>
</v-app>
</template>

修改 app.vue 檔。

1
2
3
4
5
6
7
<template>
<NuxtLayout>
<v-app>
<NuxtPage />
</v-app>
</NuxtLayout>
</template>

新增 pages/about.vue 檔。

1
2
3
4
5
6
7
8
9
10
11
<template>
<div>
<h1>About</h1>
<v-btn>
Hello
</v-btn>
<v-icon>
mdi-pen
</v-icon>
</div>
</template>

啟動本地伺服器。

1
npm run dev

前往 http://localhost:3000/about 瀏覽。

SASS variables

新增 assets/vuetify.scss 檔,以覆蓋 Vuetify 的 SASS 變數。

1
2
3
4
5
@use 'vuetify/settings' with (
$card-title-padding: 16px,
$card-text-padding: 16px,
$card-actions-padding: 16px,
);

修改 nuxt.config.js 檔,將樣式檔的路徑寫進 configFile 欄位中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify';

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
// ...
sourcemap: {
server: false,
client: false,
},
modules: [
'@pinia/nuxt',
(_options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) => {
// @ts-expect-error
config.plugins.push(vuetify({
autoImport: true,
styles: {
configFile: '/assets/vuetify.scss',
},
}));
});
},
],
// ...
});

參考資料