透過 100 多個技巧學習 Nuxt!

樣式

了解如何設定 Nuxt 應用程式的樣式。

Nuxt 在樣式方面非常彈性。您可以編寫自己的樣式,或參考本地和外部樣式表。您可以使用 CSS 預處理器、CSS 框架、UI 函式庫和 Nuxt 模組來設定應用程式的樣式。

本地樣式表

如果您正在編寫本地樣式表,自然的存放位置是assets/ 目錄

在元件內匯入

您可以直接在您的頁面、版面配置和元件中匯入樣式表。您可以使用 JavaScript 導入,或是使用 CSS 的 @import 語法

pages/index.vue
<script>
// Use a static import for server-side compatibility
import '~/assets/css/first.css'

// Caution: Dynamic imports are not server-side compatible
import('~/assets/css/first.css')
</script>

<style>
@import url("~/assets/css/second.css");
</style>
這些樣式表會被內嵌到 Nuxt 渲染的 HTML 中。

CSS 屬性

您也可以在 Nuxt 設定中使用 css 屬性。樣式表的自然位置是 assets/ 目錄。然後,您可以參考它的路徑,Nuxt 會將其包含到您應用程式的所有頁面中。

nuxt.config.ts
export default defineNuxtConfig({
  css: ['~/assets/css/main.css']
})
這些樣式表將會被內嵌到 Nuxt 渲染的 HTML 中,並全域注入到所有頁面。

處理字型

將您的本機字型檔案放置在 ~/public/ 目錄中,例如放在 ~/public/fonts 中。然後,您可以在樣式表中使用 url() 來參考它們。

assets/css/main.css
@font-face {
  font-family: 'FarAwayGalaxy';
  src: url('/fonts/FarAwayGalaxy.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

然後在您的樣式表、頁面或元件中,使用名稱來參考您的字型。

<style>
h1 {
  font-family: 'FarAwayGalaxy', sans-serif;
}
</style>

透過 NPM 發佈的樣式表

您也可以參考透過 npm 發佈的樣式表。讓我們以熱門的 animate.css 函式庫為例。

npm install animate.css

然後您就可以直接在您的頁面、版面配置和元件中參考它。

app.vue
<script>
import 'animate.css'
</script>

<style>
@import url("animate.css");
</style>

該套件也可以在您的 Nuxt 設定的 css 屬性中,以字串形式被參考。

nuxt.config.ts
export default defineNuxtConfig({
  css: ['animate.css']
})

外部樣式表

您可以在 nuxt.config 檔案的 head 區段中加入 link 元素,來將外部樣式表包含到您的應用程式中。您可以使用不同的方法來達成此結果。請注意,本機樣式表也可以用這種方式包含。

您可以使用 Nuxt 設定的 app.head 屬性來操作 head。

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
head
: {
link
: [{
rel
: 'stylesheet',
href
: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
} } })

動態新增樣式表

您可以使用 useHead composable 來在您的程式碼中動態設定 head 中的值。

請在 文件 > API > Composables > Use Head 中閱讀更多資訊。
useHead
({
link
: [{
rel
: 'stylesheet',
href
: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
})

Nuxt 在底層使用 unhead,您可以參考其完整的 文件

使用 Nitro 外掛程式修改渲染的 Head

如果您需要更進階的控制,您可以使用 hook 攔截渲染的 html,並以程式方式修改 head。

像這樣在 ~/server/plugins/my-plugin.ts 中建立一個外掛程式

server/plugins/my-plugin.ts
export default 
defineNitroPlugin
((
nitro
) => {
nitro
.
hooks
.
hook
('render:html', (
html
) => {
html
.
head
.
push
('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">')
}) })

外部樣式表是阻礙渲染的資源:它們必須先被載入和處理,瀏覽器才能渲染頁面。包含不必要的大型樣式的網頁,需要更長的時間才能渲染。您可以在 web.dev 上閱讀更多相關資訊。

使用預處理器

若要使用像是 SCSS、Sass、Less 或 Stylus 的預處理器,請先安裝它們。

npm install -D sass

撰寫樣式表的自然位置是 assets 目錄。然後,您可以使用預處理器的語法,將您的原始檔匯入到您的 app.vue (或版面配置檔案)中。

pages/app.vue
<style lang="scss">
@use "~/assets/scss/main.scss";
</style>

或者,您可以使用 Nuxt 設定的 css 屬性。

nuxt.config.ts
export default 
defineNuxtConfig
({
css
: ['~/assets/scss/main.scss']
})
在兩種情況下,編譯後的樣式表都會被內嵌到 Nuxt 渲染的 HTML 中。

如果您需要在預處理檔案中注入程式碼,例如包含顏色變數的 sass partial,您可以使用 vite 的 預處理器選項 來完成。

在您的 assets 目錄中建立一些 partial

$primary: #49240F;
$secondary: #E4A79D;

然後在您的 nuxt.config

export default 
defineNuxtConfig
({
vite
: {
css
: {
preprocessorOptions
: {
scss
: {
additionalData
: '@use "~/assets/_colors.scss" as *;'
} } } } })

Nuxt 預設使用 Vite。如果您希望改用 webpack,請參考每個預處理器載入器的 文件

預處理器 Worker (實驗性)

Vite 提供了一個 實驗性選項,可以加速使用預處理器。

您可以在您的 nuxt.config 中啟用此選項


export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorMaxWorkers: true // number of CPUs minus 1
    }
  }
})
這是一個實驗性選項,您應該參考 Vite 文件並 提供回饋

單一檔案元件 (SFC) 樣式

Vue 和 SFC 最棒的事情之一是它在處理樣式方面有多出色。您可以直接在元件檔案的 style 區塊中撰寫 CSS 或預處理器程式碼,因此您將擁有絕佳的開發人員體驗,而無需使用像 CSS-in-JS 之類的東西。但是,如果您希望使用 CSS-in-JS,您可以找到支援它的第三方函式庫和模組,例如 pinceau

您可以參考 Vue 文件,以取得有關在 SFC 中設定元件樣式的完整參考。

類別和樣式繫結

您可以利用 Vue SFC 功能,使用 class 和 style 屬性來設定元件樣式。

<script setup lang="ts">
const isActive = ref(true)
const hasError = ref(false)
const classObject = reactive({
  active: true,
  'text-danger': false
})
</script>

<template>
  <div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div>
  <div :class="classObject"></div>
</template>

請參考 Vue 文件 以取得更多資訊。

使用 v-bind 的動態樣式

您可以使用 v-bind 函式,在樣式區塊中參考 JavaScript 變數和運算式。繫結將會是動態的,這表示如果變數值變更,樣式也會更新。

<script setup lang="ts">
const color = ref("red")
</script>

<template>
  <div class="text">hello</div>
</template>

<style>
.text {
  color: v-bind(color);
}
</style>

Scoped 樣式

scoped 屬性可讓您隔離設定元件的樣式。使用此屬性宣告的樣式,只會套用到此元件。

<template>
  <div class="example">hi</div>
</template>

<style scoped>
.example {
  color: red;
}
</style>

CSS Modules

您可以使用帶有 module 屬性的 CSS Modules。使用注入的 $style 變數來存取它。

<template>
  <p :class="$style.red">This should be red</p>
</template>

<style module>
.red {
  color: red;
}
</style>

預處理器支援

SFC style 區塊支援預處理器語法。Vite 內建支援 .scss、.sass、.less、.styl 和 .stylus 檔案,無需設定。您只需要先安裝它們,它們就會直接在帶有 lang 屬性的 SFC 中可用。

<style lang="scss">
  /* Write scss here */
</style>

您可以參考 Vite CSS 文件@vitejs/plugin-vue 文件。對於 webpack 使用者,請參考 vue loader 文件

使用 PostCSS

Nuxt 內建了 postcss。您可以在 nuxt.config 檔案中設定它。

nuxt.config.ts
export default defineNuxtConfig({
  postcss: {
    plugins: {
      'postcss-nested': {},
      'postcss-custom-media': {}
    }
  }
})

為了在 SFC 中正確地使用語法高亮,您可以使用 postcss lang 屬性。

<style lang="postcss">
  /* Write postcss here */
</style>

預設情況下,Nuxt 已經預先設定了以下外掛程式

利用版面配置進行多種樣式設定

如果您需要完全不同地設定應用程式的不同部分的樣式,您可以使用版面配置。針對不同的版面配置使用不同的樣式。

<template>
  <div class="default-layout">
    <h1>Default Layout</h1>
    <slot />
  </div>
</template>

<style>
.default-layout {
  color: red;
}
</style>
請在 文件 > 指南 > 目錄結構 > 版面配置 中閱讀更多資訊。

第三方函式庫和模組

Nuxt 在樣式方面並非獨斷專行,它為您提供了多種選擇。您可以使用任何您想要的樣式工具,例如像 UnoCSSTailwind CSS 這樣的熱門函式庫。

社群和 Nuxt 團隊開發了許多 Nuxt 模組,使整合更加容易。您可以在網站的 模組區段 中找到它們。以下是一些可協助您入門的模組

  • UnoCSS:即時隨需原子 CSS 引擎
  • Tailwind CSS:實用至上的 CSS 框架
  • Fontaine:字型度量回退
  • Pinceau:適應性樣式框架
  • Nuxt UI:適用於現代 Web 應用程式的 UI 函式庫
  • Panda CSS:在建置時產生原子 CSS 的 CSS-in-JS 引擎

Nuxt 模組為您提供了開箱即用的良好開發人員體驗,但請記住,如果您的愛用工具沒有模組,並不表示您不能將它與 Nuxt 一起使用!您可以為自己的專案自行設定它。根據工具的不同,您可能需要使用 Nuxt 外掛程式 和/或 製作自己的模組。如果您這樣做了,請與 社群 分享!

輕鬆載入網頁字型

您可以使用 Nuxt Google Fonts 模組來載入 Google Fonts。

如果您使用 UnoCSS,請注意它帶有一個 網頁字型預設,可以方便地從常見的供應商載入字型,包括 Google Fonts 等。

進階

轉場

Nuxt 內建與 Vue 相同的 <Transition> 元素,並且也支援實驗性的 View Transitions API

請參閱 文件 > 開始使用 > 過場效果 以了解更多。

字體進階優化

我們建議使用 Fontaine 來減少您的 CLS。如果您需要更進階的功能,請考慮建立一個 Nuxt 模組來擴展建置流程或 Nuxt 執行時。

請始終記得利用 Web 生態系統中提供的各種工具和技術,讓您的應用程式樣式設計更輕鬆、更有效率。無論您使用的是原生 CSS、預處理器、postcss、UI 函式庫或模組,Nuxt 都能滿足您的需求。祝您樣式設計愉快!

LCP 進階優化

您可以執行以下操作來加速全域 CSS 檔案的下載速度

  • 使用 CDN,讓檔案在實體上更接近您的使用者
  • 壓縮您的資源,理想情況下使用 Brotli
  • 使用 HTTP2/HTTP3 進行傳輸
  • 將您的資源託管在同一個網域 (不要使用不同的子網域)

如果您使用的是 Cloudflare、Netlify 或 Vercel 等現代平台,這些事情大多會自動為您完成。您可以在 web.dev 上找到 LCP 優化指南。

如果您的所有 CSS 都由 Nuxt 內嵌,您可以(實驗性地)完全停止在您呈現的 HTML 中參考外部 CSS 檔案。您可以使用一個鉤子 (hook) 來實現這一點,您可以將這個鉤子放置在模組中,或放置在您的 Nuxt 設定檔中。

nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'build:manifest': (manifest) => {
      // find the app entry, css list
      const css = Object.values(manifest).find(options => options.isEntry)?.css
      if (css) {
        // start from the end of the array and go to the beginning
        for (let i = css.length - 1; i >= 0; i--) {
          // if it starts with 'entry', remove it from the list
          if (css[i].startsWith('entry')) css.splice(i, 1)
        }
      }
    },
  },
})