Description
The Problem
So as we all know, HTML is case insensitive. myProp="123"
gets parsed as myprop="123"
and this has led to the caveat in Vue.js where you have to use my-prop="123"
to refer to a prop declared in JavaScript as myProp
. This bites beginners quite often.
In addition, we also need to apply the same mapping to custom components - e.g. when you define a component:
import MyComponent from './my-component'
export default {
components: {
MyComponent // es2015 shorhand
}
}
You must use <my-component>
in the template instead of <MyComponent>
.
The annoying part here is because Vue.js relies on the browser to pre-parse the templates, by the time Vue.js gets to compile it, the case information is already lost.
The Idea
What if we adjust the matching logic so that things would just work? For example, making this possible:
<MyComponent :myProp="msg"></MyComponent>
Why?
In addition to eliminating the camelCase vs kebab-case inconsistency in our code, there are a few practical reasons why we would prefer PascalCase/camelCase for components and props:
- Props need to be referenced in templates and JavaScript as properties. Having hyphens in them makes it very awkward. (
myProp
vs.this['my-prop']
) - When we import another component, the variable name cannot be kebab case. e.g. You can do
import MyComp from './my-comp'
butmy-comp
is simply not a valid variable name. And with the ES2015 object literal shorthand you can just docomponents: { MyComp }
. - Capitalized component names stand out more vs. regular elements, making it clearer what tags are custom components and what tags are not.
Technical Details
The underlying implementation is that when we process the props and component options, we normalize them into lowercase. This way, they simply become mycomponent
and myprop
during internal matching process, but you can still use the desired case in your app code. (In fact users don't even need to know about these internals)
Potential concerns:
-
Backwards compatibility. The lowercase conversion can be done alongside the current kebab-case conversion, so both syntax can co-exist, nothing will break.
-
myProp
andMyProp
will be treated as the same thing in the template. However, it doesn't make any sense to have two props or two components in the same component differentiated only by case, and we can easily detect and warn against such usage. -
Should we apply the same rule to custom events as well? For example:
<MyComponent @myEvent="handleIt"></MyComponent>
This basically means event names become case-insensitive, which has a bigger implication than props and component names because this affects event system usage in pure javascript. Does it make sense to normalize all event names into lowercase? Again, it seems rare to have two events differentiated only by case (e.g. having both
myEvent
andmyevent
in the same app that do different things), but I do want to get feedback on this.