eslint-plugin-vue icon indicating copy to clipboard operation
eslint-plugin-vue copied to clipboard

Suggestion: a rule to enforce the style of components with a single `v-slot` directive and no other children

Open andreww2012 opened this issue 2 weeks ago • 2 comments

Please describe what the rule should do:

If a component has a single v-slot directive (commonly shortened as #), it's possible to remove an extra wrapper by moving this directive to the component directly, i.e. the following examples are equivalent:

<my-component>
  <template #default>...</template>
</my-component>

<my-component #default>...</my-component>

<my-component>...</my-component>
<my-component>
  <template #foo>...</template>
</my-component>

<my-component #foo>...</my-component>

It would be nice to have a rule to enforce a specific style in these cases.

What category should the rule belong to?

  • [x] Enforces code style (layout)
  • [ ] Warns about a potential error (problem)
  • [ ] Suggests an alternate way of doing something (suggestion)
  • [ ] Other (please specify:)

Provide 2-3 code examples that this rule should warn about:

See above

Additional context

One caveat that I see with this rule is comments handling: If a component has a single named slot and also at least one comment node outside the slot, would it be desirable to move comment nodes inside the slot when enforcing the style that avoids the additional wrapper? In other words, do we treat this

<my-component>
  <!-- some comment -->
  <template #foo>...</template>
</my-component>

the same as this:

<my-component #foo><!-- some comment -->...</my-component>

I think the default answer should be no because comment nodes are part of rendered HTML - but maybe this can be configurable via the rule option, say treatCommentsAsInsignificant.

Proposed name

single-v-slot-style

Proposed rule options

type Style = 'any' | 'with-wrapper' | 'without-wrapper';

type Options = Style /* shorthand for `style` option */ | {
  style?: Style; // Default: `any` (not enforced)
  defaultStyle?: Style; // `default` slot style. Default: inherits from `style`
  treatCommentsAsInsignificant?: boolean; // Default: false
}

andreww2012 avatar Nov 26 '25 17:11 andreww2012