Skip to content

πŸ’₯ Force camelCase in Vue everywhereΒ #1219

@ShGKme

Description

@ShGKme

Proposal

Motivation

  1. Having different cases in template and script makes it harder to find prop usage with a simple search
  2. Different tooling handle kebab-case worse, for example, with the new v-bind shortcut syntax <Tag :foo-bar /> from fooBar property, with refactoring and etc.
  3. After introducing slot-name-casing, attributes are the only with kebab-case as 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

<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

<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'

<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'

<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

<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>

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions