For AI agents: the complete documentation index is available at /annealer/zh/llms.txt, the full documentation bundle is available at /annealer/zh/llms-full.txt, and this page is available as Markdown at /annealer/zh/guide/concepts/attribute-order.md.
  • 简体中文
  • 属性顺序

    词法分析器:不构建 DOM

    annealer 不构建 DOM 或 XML 树。它找出每个起始标签(<tagname … > 或 />),并将属性列表拆分为名称/值对,只保留引号风格。

    这种方式对纯 HTML 和 Vue 的非 XML 语法(@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 模式:精确名称,或以 * 结尾的前缀。属性会进入模式与其最具体地匹配的分组:精确名称优先于任何前缀,较长的前缀优先于较短的前缀。未匹配任何模式的属性进入唯一的 fallback 分组。

    分组内的顺序由 sort 决定:

    • source:按书写顺序(默认)。
    • alphabetical:按键名。
    • listed:按 match 模式的顺序。

    HTML 配置文件

    #分组属性排序
    1globalid
    2classclass
    3supplementaryalt, title, placeholderlisted
    4semantictype, href, src, srcsetlisted
    5key-valuename, value, contentlisted
    6dimensionswidth, heightlisted
    7other (fallback)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,且后出现的声明优先;对于其他重复名称,Vue 只保留其中一个。重新排序可能改变行为。
    • v-model 从不与同名的普通属性聚合(value="x" v-model="y")。它的键是 v-model 而非 value,并且由于双向绑定是不同的概念,它保持在自己的层级中。

    v-bind 展开

    v-bind="object" 是一个边界。属性从不会跨越展开移动,因为这可能改变对象合并时哪个值优先。

    例外是标记为 spreadSafe 的分组。它们是编译期指令(is、v-for、v-if/…、v-pre/v-once、自定义指令),从不与展开对象合并,因此可以跨越展开移动。其他所有属性都保持在各自的片段内。

    规范化

    Vue 配置文件启用了两种改写,在分类之前执行:

    • directiveShorthand:v-bind:foo → :foo,v-on:click → @click。
    • hyphenateComponentProps:组件标签上的 camelCase 属性名 → kebab-case(:itemName → :item-name)。原生 SVG 和 MathML 元素不受影响。