-
Notifications
You must be signed in to change notification settings - Fork 4
Closed
Labels
Description
Proposal
- β
vue/component-definition-name-casing:[2, 'PascalCase'](default, used viavue/strongly-recommended) - β
vue/component-name-in-template-casing:[2, 'PascalCase](default, used manually) - β
vue/component-options-name-casing:[2, 'PascalCase', { registeredComponentsOnly: true }](add rule, used de-facto) - β
vue/prop-name-casing:[2, 'camelCase'](default, used viavue/strongly-recommended) - β
vue/custom-event-name-casing:[2, 'camelCase'](add rule, default and used de-facto) - π₯
vue/v-on-event-hyphenation:[2, 'camelCase'](opposite, change) - π₯
vue/attribute-hyphenation:[2, 'never'](opposite, change) - β
vue/slot-name-casing:[2, 'camelCase'](default, add rule)
Motivation
- Having different cases in template and script makes it harder to find prop usage with a simple search
- Different tooling handle
kebab-caseworse, for example, with the newv-bindshortcut syntax<Tag :foo-bar />fromfooBarproperty, with refactoring and etc. - After introducing
slot-name-casing, attributes are the only withkebab-caseas the default recommendation (but not forced)
Isn't it against Vue Style Guide?
Not really, now both styles are correct if consistent: https://vuejs.org/style-guide/rules-strongly-recommended.html#prop-name-casing
In addition, the Vue Style Guide is:
- Not permanent: just recently
<kebab-case>was the recommended default to component names in the template - Not consistent: PascalCase/camelCase for components, event, slots and kebab for props
- Sometimes slow to adapt: before supporting in-dom templates was more important than nowadays, Vue 3 Style Guide was in active development for a long time after the Vue 3 release
Detailed
Existing rules
vue/component-definition-name-casing:[2, 'PascalCase'](β default, used viavue/strongly-recommended)vue/component-name-in-template-casing:[2, 'PascalCase](β default, used manually)vue/prop-name-casing:[2, 'camelCase'](β default, used viavue/strongly-recommended)
<script>
import NcComponent from './NcComponent.vue'
export default {
name: 'MyApp', // β
Good
name: 'my-app', // β Bad
components: {
NcComponent,
},
props: {
componentProp: { // β
Good
type: Number,
required: true,
},
'component-prop': { // β Bad
type: Number,
required: true,
},
},
}
</script>
<template>
<NcComponent /> <!-- β
Good -->
<nc-component /> <!-- β Bad -->
</template>Add rules for what we have de-facto
vue/custom-event-name-casing:[2, 'camelCase']vue/component-options-name-casing:[2, 'PascalCase', { registeredComponentsOnly: true }]
<script>
import NcComponent from './NcComponent.vue'
export default {
name: 'MyApp',
components: {
NcComponent, // β
Good
'nc-component': NcComponent, // β Bad
},
emits: [
'componentEvent',
'component-event',
],
}
</script>
<template>
<button @click="$emit('componentEvent')" /> <!-- β
Good -->
<button @click="$emit('component-event')" /> <!-- β Bad -->
</template>Change events in template from 'kebab-case' to 'camelCase'
vue/v-on-event-hyphenation:[2, 'camelCase'](π₯ opposite, change)
<template>
<!-- β
Good -->
<MyComponent @customEvent="handleEvent" />
<!-- β
Also fine -->
<MyComponent @namespace:customEvent="handleEvent" />
!-- β Bad -->
<MyComponent @custom-event="handleEvent" />
</template>Change attrs/props in template from 'kebab-case' to 'camelCase'
vue/attribute-hyphenation:[2, 'never'](π₯ opposite, change)
<script setup>
const myShortcut = 'value'
</script>
<template>
<!-- β
Good -->
<MyComponent myProp="value" :myShortcut myBoolean />
<!-- β
Also fine -->
<MyComponent aria-label="label" data-attr="value" />
!-- β Bad -->
<MyComponent my-prop="value" :my-shortcut my-boolean />
</template>Add rule for slot definition
vue/slot-name-casing:[2, 'camelCase'](β default, add the rule)
<script setup lang="ts">
import type { Slot } from 'vue'
defineSlots<{
mySlot: Slot // β
Good
'my-slot': Slot // β Bad
}>()
</script>
<template>
<!-- β
Good -->
<slot name="mySlot" />
!-- β Bad -->
<slot name="my-slot" />
</template>Reactions are currently unavailable