Skip to content

SFC 作成規則

10.4.1. ブロック順序

SFC(Single File Component) 内のブロックは以下の順序に従います。

  1. <script setup lang="ts"> — ロジック
  2. <template> — マークアップ
  3. <style scoped> — スタイル
vue
<script setup lang="ts">
import { ref } from 'vue'

const message = ref('Hello')
</script>

<template>
  <p>{{ message }}</p>
</template>

<style scoped>
p {
  color: inherit;
}
</style>

必須

ESLint vue/block-order ルールがこの順序を強制します。違反した場合、リントエラーが発生します。


10.4.2. template 作成規則

  • v-html使用しません。 XSS 攻撃に脆弱です。やむを得ない場合は DOMPurify でサニタイズした後に使用します。
  • v-for には必ず :key をバインドします。index を key として使用しません。
  • v-ifv-for を同じ要素に同時に使用しません。<template> タグで分離します。
vue
<!-- 正しい例 -->
<template v-for="item in items" :key="item.id">
  <div v-if="item.isActive">
    {{ item.name }}
  </div>
</template>

<!-- 誤った例 -->
<div v-for="item in items" v-if="item.isActive" :key="item.id">
  {{ item.name }}
</div>

10.4.3. 属性バインディング規則

  • 静的属性は通常の HTML 属性として、動的属性は v-bind(:) 省略記法で記述します。
  • boolean 属性は値なしで宣言して true を渡します。
  • 属性が3つ以上の場合、1行に1つずつ配置します。
vue
<!-- 属性が3つ以上 — 1行に1つずつ -->
<UserCard
  :user="currentUser"
  :editable="isAdmin"
  :loading="isLoading"
  @update="handleUpdate"
/>

<!-- boolean 属性 -->
<BaseButton
  primary
  disabled
  @click="handleClick"
/>

10.4.4. イベントハンドリング

  • イベントハンドラーは @ 省略記法を使用します。v-on は使用しません。
  • インラインハンドラーは単純な式(1行)にのみ許容します。
  • 複雑なロジックは別の関数に分離します。
vue
<script setup lang="ts">
function handleSubmit() {
  // 複雑なロジック
}
</script>

<template>
  <!-- 正しい例: 単純な式 -->
  <button @click="count++">増加</button>

  <!-- 正しい例: 関数参照 -->
  <form @submit.prevent="handleSubmit">
    <!-- ... -->
  </form>
</template>

10.4.5. style 規則

  • <style> タグには必ず scoped を使用します。グローバルスタイルは src/styles/ ディレクトリで管理します。
  • :deep() セレクターは子コンポーネントのスタイルオーバーライド時にのみ限定的に使用します。
  • Tailwind CSS ユーティリティクラスを優先的に使用し、カスタム CSS は最小限にします。
vue
<style scoped>
/* scoped スタイル */
.container {
  @apply flex items-center gap-4;
}

/* 子コンポーネントのスタイルオーバーライド(限定的に許容) */
:deep(.child-class) {
  color: inherit;
}
</style>

TIENIPIA QUALIFIED STANDARD