Skip to content

HTML case sensitivity workaround #2308

Closed
@yyx990803

Description

@yyx990803

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:

  1. Props need to be referenced in templates and JavaScript as properties. Having hyphens in them makes it very awkward. (myProp vs. this['my-prop'])
  2. When we import another component, the variable name cannot be kebab case. e.g. You can do import MyComp from './my-comp' but my-comp is simply not a valid variable name. And with the ES2015 object literal shorthand you can just do components: { MyComp }.
  3. 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:

  1. Backwards compatibility. The lowercase conversion can be done alongside the current kebab-case conversion, so both syntax can co-exist, nothing will break.

  2. myProp and MyProp 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.

  3. 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 and myevent in the same app that do different things), but I do want to get feedback on this.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions