For AI agents: the complete documentation index is available at /annealer/ja/llms.txt, the full documentation bundle is available at /annealer/ja/llms-full.txt, and this page is available as Markdown at /annealer/ja/guide/concepts/attribute-order.md.
  • 日本語
  • 属性順

    字句解析: DOM を構築しない

    annealer は DOM や XML のツリーを構築しません。開始タグ(<tagname … > または />)を見つけ、属性リストを名前と値の組に分割し、引用符の種類だけを記録します。

    この方式は素の HTML でも、XML に準拠しない Vue の構文(@click、#default、v-bind:[dynamic])でも同じように動きます。また、DOM や XML ベースの解析で起こる、空白のまとめ込みやタグ名・属性名の小文字化といった副作用も避けられます。

    生テキスト要素、コメント、{{ }} の補間、SFC の <script> ブロック、カスタムブロック、HTML 以外の言語を指定した <template lang="…"> は読み飛ばします。

    分類

    各属性は正規化したキーで分類します。

    書き方キー
    foo、:foo、v-bind:foofoo
    @click、v-on:clickv-on:click
    #item、v-slot:itemv-slot:item
    @click.stop、:foo.camel修飾子を除去

    プロファイルは、出力順に並んだグループのリストです。各グループは match パターン(完全一致の名前、または * で終わるプレフィックス)を持ちます。属性は、最も具体的に一致するパターンのグループに入ります。完全一致はどのプレフィックスよりも優先され、長いプレフィックスは短いものより優先されます。どれにも一致しない属性は、ただ 1 つのフォールバックグループに入ります。

    グループ内の順序は sort で決まります。

    • source: 書かれた順(既定)
    • alphabetical: キーのアルファベット順
    • listed: match パターンの並び順

    HTML プロファイル

    #グループ属性ソート
    1globalid
    2classclass
    3supplementaryalt、title、placeholderlisted
    4semantictype、href、src、srcsetlisted
    5key-valuename、value、contentlisted
    6dimensionswidth、heightlisted
    7other(フォールバック)disabled、checked、readonly などの状態属性source
    8aria-rolerole
    9aria-namearia-label、aria-labelledbylisted
    10aria-descriptionaria-describedby、aria-description、aria-detailslisted
    11aria-propertyその他の aria-*source
    12aria-statearia-busy、aria-checked、aria-current、aria-disabled、aria-expanded、aria-grabbed、aria-hidden、aria-invalid、aria-pressed、aria-selectedsource
    13datadata-*alphabetical
    14eventson*source

    この順序にした理由:

    • 補足属性は id/class の直後に置きます。 人間の読み手に向けて要素を説明する属性だからです。id と class は慣用的に並べて書かれるため、先頭にまとめます。
    • ARIA は末尾近くに置きます。 alt/title では表現できない、支援技術向けの追加メタデータであり、要素の主たる説明ではないからです。
    • ARIA の中は WAI-ARIA に従います: role → アクセシブルな名前 → 説明 → プロパティ → ステート
    • data-* はアルファベット順です。 意味に基づく順序が存在しないためです。

    Vue プロファイル

    Vue プロファイルは eslint-plugin-vue の vue/attributes-order の既定順に従うため、出力は常にそのルールを満たします。

    #階層属性
    1定義is、v-is
    2リストレンダリングv-for
    3条件v-if、v-else-if、v-else、v-show、v-cloak
    4レンダー修飾子v-pre、v-once
    5グローバルid
    6一意/スロットref、key、slot、v-slot*
    7双方向バインディングv-model*
    8aその他のディレクティブその他の v-*
    8bその他の属性HTML プロファイルの class から data までのグループ(上記)
    9イベントv-on*(@…)
    10コンテンツv-html、v-text

    階層 8 は「その他のディレクティブ」→「その他の属性」の順に分かれています。これは vue/attributes-order の OTHER_DIRECTIVES → OTHER_ATTR に合わせたものです。HTML プロファイルの細分化は「その他の属性」の階層内で適用されます。

    <!-- 入力 -->
    <MyItem
      @click="select"
      :class="{ active }"
      class="item"
      v-for="item in items"
      :key="item.id"
      aria-label="Item"
      v-bind:title="item.name"
      :itemName="item.name"
    />
    
    <!-- 出力 -->
    <MyItem
      v-for="item in items"
      :key="item.id"
      class="item"
      :class="{ active }"
      :title="item.name"
      :item-name="item.name"
      aria-label="Item"
      @click="select"
    />

    同名クラスタリング

    分類は正規化したキーで行うため、同じ属性の静的形式とバインド形式は同じキーになり、まとまって並びます。キーが最初に現れた位置がそのクラスタの位置になります。特別な処理は必要ありません。

    • class は静的形式をバインド形式より前に置きます(class="item" :class="{ active }")。
    • その他の名前はクラスタ内で書かれた順を保ちます。Vue は style を後の宣言が勝つ形でマージし、それ以外の重複した名前は一方しか残さないため、並べ替えると動作が変わるおそれがあるからです。
    • v-model は同名の通常属性とクラスタにしません(value="x" v-model="y")。キーは value ではなく v-model であり、双方向バインディングは別の概念なので独自の階層に残ります。

    v-bind スプレッド

    v-bind="object" は境界として扱います。オブジェクトのマージ時にどの値が勝つかが変わるおそれがあるため、属性をスプレッドをまたいで移動しません。

    例外は spreadSafe を指定したグループです。これはスプレッドオブジェクトとマージされることのないコンパイル時ディレクティブ(is、v-for、v-if など、v-pre/v-once、カスタムディレクティブ)なので、スプレッドをまたいで移動できます。それ以外はすべて自分のセグメント内に留まります。

    正規化

    Vue プロファイルでは 2 つの書き換えが有効で、分類の前に実行されます。

    • directiveShorthand: v-bind:foo → :foo、v-on:click → @click
    • hyphenateComponentProps: コンポーネントタグ上の camelCase の属性名 → kebab-case(:itemName → :item-name)。SVG や MathML のネイティブ要素は対象外です。