Vue3 元件基礎:元件命名規則(PascalCase vs kebab-case)
簡介
在 Vue3 專案中,元件的命名方式不僅影響程式碼的可讀性,還會直接牽涉到編譯器的解析規則、IDE 的自動補全以及團隊協作的統一性。
雖然 Vue 本身在模板中接受兩種寫法——PascalCase(大寫駝峰)與 kebab-case(短線小寫),但在實務開發時若缺乏明確的規範,往往會出現 命名不一致、樣式衝突或錯誤無法偵測 等問題。
本篇文章將深入比較兩種命名風格的差異、最佳使用時機,並提供實作範例與常見陷阱,幫助你在 Vue3 專案中建立 乾淨、易維護 的元件命名慣例。
核心概念
1. 什麼是 PascalCase 與 kebab-case?
| 風格 | 範例 | 說明 |
|---|---|---|
| PascalCase | MyButton、UserProfileCard |
每個單字首字母大寫,沒有分隔符。常見於 JavaScript/TypeScript 中的類別、變數命名。 |
| kebab-case | my-button、user-profile-card |
所有字母小寫,單字以 短線(-) 分隔。符合 HTML 標籤的慣例,也是瀏覽器原生解析的方式。 |
重要:在 Vue 的
<template>中,兩者皆可使用;但在 單檔元件(SFC) 的import語句與 全局註冊 時,建議保持一致的寫法,以免產生混淆。
2. Vue 內部如何處理命名?
Vue 在編譯模板時會將 kebab-case 轉換為 PascalCase,反之亦然。舉例:
<!-- 兩者皆可正確渲染同一個元件 -->
<MyButton></MyButton>
<my-button></my-button>
編譯器會先把 my-button 轉成 MyButton,再在註冊表中尋找對應的元件定義。
然而,在 JavaScript/TypeScript 中引用時,只能使用 PascalCase(或駝峰式):
import MyButton from '@/components/MyButton.vue';
3. 為什麼要選擇其中一種風格?
| 考量 | PascalCase | kebab-case |
|---|---|---|
| 可讀性 | 在程式碼中顯示為類別,直觀易懂 | 在 HTML 中更貼近原生標籤語法 |
| IDE 支援 | 大多數 IDE 在自動補全、跳轉時對 PascalCase 有較好支援 | 在模板編輯器中,kebab-case 可直接使用 HTML 片段的語法高亮 |
| 團隊一致性 | 方便在 JavaScript/TS 中與其他類別保持命名風格一致 | 符合設計系統(Design System)常用的 CSS class 命名習慣 |
| SSR / 靜態分析 | 需要在編譯階段正確解析,PascalCase 更安全 | 若使用自訂的 webpack / Vite 別名,kebab-case 可能需要額外設定 |
結論:在 Vue3 官方文件 與 大多數開源套件 中,PascalCase 被推薦作為 元件檔案與變數名稱,而 kebab-case 則適用於 模板內的標籤寫法。最重要的是在同一個專案內保持統一。
4. 範例:不同命名方式的元件建立與使用
4.1 使用 PascalCase 建立與全局註冊
// src/components/BaseButton.vue
<template>
<button class="base-button"><slot /></button>
</template>
<script setup>
export default {
name: 'BaseButton' // 建議保持 PascalCase
}
</script>
<style scoped>
.base-button { /* CSS 可使用 kebab-case */ }
</style>
// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import BaseButton from '@/components/BaseButton.vue';
const app = createApp(App);
app.component('BaseButton', BaseButton); // 全局註冊使用 PascalCase
app.mount('#app');
4.2 在模板中使用 kebab-case(或 PascalCase)均可
<!-- App.vue -->
<template>
<!-- 兩種寫法皆可 -->
<BaseButton>按鈕 A</BaseButton>
<base-button>按鈕 B</base-button>
</template>
4.3 局部註冊時的寫法差異
// src/views/HomeView.vue
<script setup>
import MyCard from '@/components/MyCard.vue';
export default {
components: {
// 直接使用 PascalCase
MyCard,
// 也可以使用 kebab-case,Vue 會自動映射
'my-card': MyCard
}
}
</script>
<template>
<MyCard title="卡片標題" />
<my-card title="另一張卡片" />
</template>
4.4 動態載入(Lazy Loading)時的命名
// src/router/index.js
{
path: '/profile',
component: () => import('@/components/UserProfile.vue') // 檔案名稱使用 PascalCase
}
在路由懶加載的情境下,檔案名稱仍建議使用 PascalCase,因為這樣在 IDE 中可直接定位到相對應的元件。
4.5 結合 TypeScript 時的最佳實踐
// src/components/AlertBox.vue
<template>
<div class="alert-box"><slot /></div>
</template>
<script lang="ts" setup>
import { defineProps } from 'vue';
interface Props {
type: 'success' | 'error' | 'warning';
}
defineProps<Props>();
</script>
// src/components/index.ts
export { default as AlertBox } from './AlertBox.vue'; // PascalCase 匯出
在 TypeScript 中,匯出與匯入皆使用 PascalCase,可享受完整的型別推斷與自動補全。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 |
|---|---|---|
| 混用大小寫 | 同一元件在不同檔案使用 MyButton 與 my-button,導致找不到元件。 |
於 eslint-plugin-vue 設定 vue/component-name-in-template-casing,強制統一寫法。 |
| 全局註冊與局部註冊衝突 | 全局註冊 BaseButton,局部又以 base-button 引入,可能被覆寫。 |
盡量使用 局部註冊,或在全局註冊時統一使用 PascalCase。 |
| CSS 選擇器與元件名稱混淆 | 把元件名稱寫成 .BaseButton,在 SCSS 中與實際 HTML 標籤不匹配。 |
CSS 請使用 kebab-case(如 .base-button),保持與 HTML 標籤一致。 |
| 懶加載路徑大小寫錯誤 | Windows 開發環境不區分大小寫,部署到 Linux 時路徑錯誤。 | 始終使用正確大小寫,並在 CI/CD 中加入大小寫檢查。 |
| 自訂指令或插件的命名衝突 | 例如自訂指令 v-my-button 與元件 MyButton 同名。 |
為指令加上前綴(如 v-app-my-button),避免衝突。 |
推薦的 ESLint 設定
{
"plugins": ["vue"],
"rules": {
"vue/component-name-in-template-casing": ["error", "PascalCase", {
"registeredComponentsOnly": true,
"ignores": []
}],
"vue/component-definition-name-casing": ["error", "PascalCase"]
}
}
使用上述規則可在 編寫模板時即時警告,避免大小寫不一致的問題。
實際應用場景
大型企業內部 UI 套件
- 元件檔案與匯出使用 PascalCase(如
DataTable.vue),方便在 TypeScript 中做型別擴充。 - 在設計系統文件(Storybook)或 HTML 範例中,使用 kebab-case 讓前端設計師直接貼上
<data-table>。
- 元件檔案與匯出使用 PascalCase(如
跨平台(Web + Native)開發
- 在 Vue 3 + Vite + Capacitor 專案中,
<my-modal>會被原生 WebView 直接解析,保持 kebab-case 可減少平台差異。
- 在 Vue 3 + Vite + Capacitor 專案中,
插件或第三方套件開發
- 若要發佈 npm 套件,官方文件建議 使用 PascalCase 作為元件名稱,並在
package.json中提供module、main兩個入口,讓使用者在import { MyComponent } from 'my-lib'時感受一致性。
- 若要發佈 npm 套件,官方文件建議 使用 PascalCase 作為元件名稱,並在
SSR(Server‑Side Rendering)
- Nuxt3(基於 Vue3)在自動路由生成時會將檔案名稱(PascalCase)轉成 URL(kebab-case),保持檔案與元件名稱的一致性有助於路由正確匹配。
總結
- PascalCase 適合作為 檔案名稱、變數、匯出,在 JavaScript/TypeScript 與全局註冊時提供最佳的 IDE 支援與型別安全。
- kebab-case 則是 模板內的 HTML 標籤寫法,符合瀏覽器原生解析規則,對設計師與非程式人員更友善。
- 統一規範 是避免命名衝突、提升可維護性的關鍵:在專案中選擇一種風格(建議 PascalCase 為主),並透過 ESLint、Prettier 以及團隊程式碼審查來強制執行。
- 了解 Vue 的編譯機制、懶加載與跨平台差異,才能在實務開發中正確運用兩種命名方式,讓元件的可讀性、可測試性與可擴充性同步提升。
實務小技巧:在新建元件時,先在
components/目錄下以 PascalCase 命名檔案,模板內直接使用 kebab-case,如此既符合 IDE 的自動補全,又保持 HTML 的可讀性,兩全其美。祝你在 Vue3 的開發旅程中,寫出乾淨、易維護的元件!