Vue: Solución de distinción de mayúsculas y minúsculas HTML

Creado en 6 feb. 2016  ·  48Comentarios  ·  Fuente: vuejs/vue

El problema

Entonces, como todos sabemos, HTML no distingue entre mayúsculas y minúsculas. myProp="123" se analiza como myprop="123" y esto ha llevado a la advertencia en Vue.js donde debe usar my-prop="123" para referirse a una propiedad declarada en JavaScript como myProp . Esto muerde a los principiantes con bastante frecuencia.

Además, también debemos aplicar la misma asignación a los componentes personalizados, por ejemplo, cuando define un componente:

import MyComponent from './my-component'

export default {
  components: {
    MyComponent // es2015 shorhand
  }
}

Debe usar <my-component> en la plantilla en lugar de <MyComponent> .

La parte molesta aquí es que Vue.js se basa en el navegador para analizar previamente las plantillas, cuando Vue.js llega a compilarlas, la información del caso ya se ha perdido.

La idea

¿Qué pasa si ajustamos la lógica de coincidencia para que las cosas simplemente funcionen? Por ejemplo, haciendo esto posible:

<MyComponent :myProp="msg"></MyComponent>

¿Por qué?

Además de eliminar la inconsistencia camelCase vs kebab-case en nuestro código, hay algunas razones prácticas por las que preferiríamos PascalCase/camelCase para componentes y accesorios:

  1. Los accesorios deben estar referenciados en plantillas y JavaScript como propiedades. Tener guiones en ellos lo hace muy incómodo. ( myProp frente a this['my-prop'] )
  2. Cuando importamos otro componente, el nombre de la variable no puede ser un caso de kebab. por ejemplo, puede hacer import MyComp from './my-comp' pero my-comp simplemente no es un nombre de variable válido. Y con la abreviatura literal del objeto ES2015, puede hacer components: { MyComp } .
  3. Los nombres de los componentes en mayúscula se destacan más que los elementos regulares, lo que deja más claro qué etiquetas son componentes personalizados y qué etiquetas no lo son.

Detalles técnicos

La implementación subyacente es que cuando procesamos las opciones de accesorios y componentes, las normalizamos en minúsculas. De esta manera, simplemente se convierten en mycomponent y myprop durante el proceso de coincidencia interna, pero aún puede usar el caso deseado en el código de su aplicación. (De hecho, los usuarios ni siquiera necesitan saber acerca de estos componentes internos)

Preocupaciones potenciales:

  1. Compatibilidad al revés. La conversión a minúsculas se puede realizar junto con la conversión de mayúsculas y minúsculas actual, por lo que ambas sintaxis pueden coexistir, nada se romperá.
  2. myProp y MyProp se tratarán como lo mismo en la plantilla. Sin embargo, no tiene ningún sentido tener dos accesorios o dos componentes en el mismo componente diferenciados solo por mayúsculas y minúsculas, y podemos detectar y advertir fácilmente contra dicho uso.
  3. ¿Deberíamos aplicar la misma regla a los eventos personalizados también? Por ejemplo:

html <MyComponent @myEvent="handleIt"></MyComponent>

Básicamente, esto significa que los nombres de los eventos no distinguen entre mayúsculas y minúsculas, lo que tiene una implicación mayor que los nombres de accesorios y componentes porque esto afecta el uso del sistema de eventos en javascript puro. ¿Tiene sentido normalizar todos los nombres de eventos en minúsculas? Nuevamente, parece raro tener dos eventos diferenciados solo por caso (por ejemplo, tener myEvent y myevent en la misma aplicación que hacen cosas diferentes), pero quiero recibir comentarios al respecto.

discussion

Comentario más útil

La única regla para memorizar: HTML = kebab-case, JavaScript = camelCase

Por HTML me refiero a atributos y etiquetas. Los valores de atributo son expresiones de JavaScript cuando usa v-bind , por lo que se aplica la segunda declaración.

Todos 48 comentarios

<MyComponent :myProp="msg"></MyComponent>

+
A menudo quiero escribir de esa manera para ver la diferencia entre los componentes y las etiquetas.

+1

¿Tiene sentido normalizar todos los nombres de eventos en minúsculas?

¡Sí! Tiene sentido, porque hace que el código sea más legible. Siempre mantengo los nombres de los eventos en minúsculas, los separo con guiones, en lugar de camelcase. Creo que agregar una advertencia para los nombres de eventos de camelcase también sería bueno.

¿Significa esto que Vuejs se alejará de la especificación HTML y seguirá un enfoque similar al de Angular ?

¿Hay algún problema de rendimiento?

Un par de pensamientos sobre las posibles preocupaciones:

  1. Siempre que exista compatibilidad con versiones anteriores, estaré bien con lo que se decida finalmente, pero probablemente continuaré usando el método de caso de kebab.
  2. La falta de distinción entre camel-case y minúscula camel-case puede resultar confuso para algunos. En términos generales var CamelCase se referiría a una clase y var camelCase se referiría a una variable que no es de clase, var camelCase = new CamelCase(); . Pero no creo que esto sea un problema, porque no querría crear clases con el nombre de sus componentes.
  3. Estoy de acuerdo en que crear dos eventos únicos que solo se distingan por el caso sería una programación muy pobre.

Mi mayor preocupación es introducir extrañas inconsistencias con la forma en que la gente codifica. Por ejemplo, todos estos son válidos e idénticos: :myprop="" :myProp="" :mYpRoP="" :my-prop="" .

👎 Mantenga kebab-case en el marcado y camel case en el código. Es parte de la especificación HTML e ignorar el caso será una mayor curva de aprendizaje para aquellos que vienen de otros marcos o que ya han aprendido el estándar.

Estoy de acuerdo con @Teevio , se perderá la consistencia.

HTML usa kebab-case y es un estándar comunitario aceptado que ECMAScript es un lenguaje camelCase. Deberíamos mantenerlos separados en lugar de _ocultarlos_ (en reaccionar, la única forma en que puede reaccionar para representar el atributo personalizado es a través de datos-* y aria-*, lo que impone la coherencia).

Explicar por qué (digamos a través del enlace MDN o incluso aquí) camelCase <-> kebab-case a un _principiante_ ayudará mucho a la comprensión de HTML del principiante.

De acuerdo con Evan, ¡la legibilidad y la consistencia del código son más importantes!
+1

A mí me parecerá muy raro tener camelCase dentro de HTML.

HTML es HTML, JS es JS

la versión actual está bien

Habiendo estado usando Vue durante 6 meses, eso todavía me atrapa cada vez :( no es gran cosa ya que las advertencias para Vue son tan buenas que sé lo que hice, pero puedo entender completamente la idea aquí y apoyarla +1

+1 Compatibilidad con versiones anteriores también.

+1
Estuve de acuerdo. tenemos que mantener la compatibilidad con versiones anteriores.

¿Tiene sentido normalizar todos los nombres de eventos en minúsculas?

Estoy de acuerdo con @azamat-sharapov

Los componentes de @Teevio Vue son aproximadamente clases: cuando haces var MyComp = Vue.extend({ .. }) , puedes hacer var myComp = new MyComp() . En cuanto al problema de sintaxis válida múltiple, ya existe: :my-prop , :MY-PROP y :mY-pRop todos funcionan igual a partir de ahora, porque HTML simplemente descarta toda la información del caso. No es muy diferente con la característica propuesta. Al igual que con todos los argumentos de estilo, se trata de elegir un estilo y apegarse a él.

Re @jamesxv7 @moe-szyslak @jonagoldman y otros que están preocupados por alejarse del estándar HTML: es totalmente válido escribir etiquetas/atributos de camelCase en HTML, es solo que la coincidencia de nombre de etiqueta/atributo se realizará sin distinguir entre mayúsculas y minúsculas . Esto es lo que dice la especificación :

En documentos en la sintaxis HTML:

Los nombres de las etiquetas para los elementos HTML se pueden escribir con cualquier combinación de letras mayúsculas y minúsculas que no distingan entre mayúsculas y minúsculas para los nombres de los elementos proporcionados en la sección de elementos HTML de este documento; es decir, los nombres de las etiquetas no distinguen entre mayúsculas y minúsculas.
Los nombres de los atributos de los elementos HTML se pueden escribir con cualquier combinación de letras mayúsculas y minúsculas que no distingan entre mayúsculas y minúsculas para los nombres de los atributos proporcionados en la sección de elementos HTML de este documento; es decir, los nombres de los atributos no distinguen entre mayúsculas y minúsculas.

Entonces, si usar PascalCase/camelCase mejora la consistencia/legibilidad del código, es totalmente compatible con las especificaciones para hacerlo. Puede que esto no sea para todos, pero si prefiere el estuche de kebab, puede seguir usándolo.

Y en particular, re @jamesxv7 : esto es diferente de lo que está haciendo Angular 2. Angular 2 está haciendo que sus plantillas distingan entre mayúsculas y minúsculas mediante la introducción de un analizador HTML personalizado. Por el contrario, Vue en realidad sigue la especificación al hacer que las contrapartes de JS no distingan entre mayúsculas y minúsculas.

Prefiero mantener kebab en html. Me gusta la idea de la coherencia, pero me gusta más la idea del cumplimiento de las especificaciones.

Etiqueta camelCase encontrada:. HTML no distingue entre mayúsculas y minúsculas. Usaren lugar de. Vue lo comparará automáticamente con los componentes definidos con ID de camelCase en JavaScript.

Esta advertencia ya es bastante concisa en cuanto a cómo funciona el registro de componentes. Dicho esto, como han mencionado otros, creo que permitir camelCase en HTML es excelente, siempre que exista la opción de continuar escribiendo kebab.

@ yyx990803 sí , de acuerdo. Solo trato de pensar en tantos argumentos como pueda en contra, pero honestamente no tengo ninguno que se mantenga. Como mencionaste, al final del día estamos discutiendo elecciones estilísticas. Personalmente, creo que mientras podamos seguir con lo que ya tenemos y tener la opción de usar las cosas nuevas (pero no forzados a hacerlo), estoy de acuerdo con los cambios mencionados.

Si kebab-case todavía funciona y usar camelCase/ PascalCase es una opción que no rompe BC, cuando los uso, entonces no puedo estar en contra de la adición. No es un cambio que me obligue a hacer algo diferente. Es solo una nueva opción.

Lo único que puedo decir o sugerir es asegurarme de que esta opción esté bien documentada y - ¡Buen trabajo, como siempre, Evan!

scott

Tal vez podamos hacer una opción: advertir o ignorar.
Digamos que tengo un componente: myComponent
y me refiero a él en html como mycompOnent Personalmente preferiría una advertencia, como:
we found something that would match "myComponent": "mycompOnent" (line 152), use "my-component" instead
Lo mismo para los accesorios, por supuesto.
Creo que la legibilidad posterior es más importante que que todo funcione en el primer intento.

También encontré problemas con kebab-case/camelCase. Pero el problema real fue que no recibí advertencias de lo que estaba mal;)

El valor predeterminado podría ser que no haya advertencia y simplemente funcione, eso es irrelevante para mí.
Además, las advertencias deberían ser visibles solo en modo de depuración, creo.

¿Qué pasa con cosas como atone frente a a-tone frente a at-one ? Aunque me imagino que son casos bastante raros.

Los accesorios de caja de @simplesmiler kebab aún se combinarían con la distinción entre mayúsculas y minúsculas usando reglas antiguas.

Esto no promueve la transparencia de los estándares web. La especificación de elementos personalizados establece que los nombres deben contener un guión: <my-component/>

¿Qué pasa con lo que dijo @simplesmiler : addOne y adDone ejecutarían el mismo código? Esto sería especialmente desagradable para la implementación de eventos,

Y debido a que html no distingue entre mayúsculas y minúsculas, no introduzcamos la idea de mayúsculas y minúsculas de la biblioteca. Esta implementación solo promovería el uso de mayúsculas y minúsculas en html, lo que en mi opinión es una mala idea.

Además, usamos la separación de guiones en los nombres de los archivos. ¿Deberíamos eliminarlos allí también y comenzar a agregar carcasa?

Por último: la coexistencia del sistema de hypen y casing promueve diferentes estilos de codificación para los nuevos desarrolladores en un equipo.

Prefiero el enfoque de @paulpflug ; Las advertencias adecuadas en esta área ayudarían mucho.

No soy fanático de hacer el caso HTML Pascal/Camel. Rompe los estándares web, sé que es bueno mantener la coherencia.

Al tratar de hacer que las cosas sean lo más mínimamente consistentes, agrega otra capa de complejidad. También puede ser tentadoras malas prácticas. Una biblioteca debe promover el cumplimiento de los estándares y no engañar a los desarrolladores, ya que es posible que algún día tengan que trabajar en un lugar que no use Vue, lo que resultará en no comprender por qué el HTML se analiza de manera diferente.

Estoy totalmente de acuerdo con @paulpflug : agregar una advertencia significa menos trabajo para el código de producción y vuelve a encaminar a los desarrolladores para escribir código válido.

Un buen argumento de por qué esto no debería implementarse: http://eisenbergeffect.bluespire.com/on-angular-2-and-html/

Esta es comúnmente una razón destacada por la que a las personas no les gusta Angular 2. Estoy totalmente de acuerdo con mantener las bibliotecas conforme a los estándares. Una vez se redactó para que HTML distinguiera entre mayúsculas y minúsculas, y se desechó debido a demasiados problemas y a la apertura de situaciones de demasiada flexibilidad.

@blake-newman: Con respecto a esto , creo que @yyx990803 ya habló de eso en un comentario anterior.

@jamesxv7 Ese comentario lo resume bastante bien; Evan no propone cambiar las especificaciones de HTML, propone cambiar la forma en que Vue ubica los nombres de los componentes. En lugar de convertir kebab en camello y encontrar el componente coincidente, probablemente quitaría guiones (para acomodar kebab) y luego buscaría componentes sin distinción entre mayúsculas y minúsculas. El propio HTML seguirá cumpliendo con las especificaciones. También nos permitiría usar cualquier caso que queramos. Esto no me parece una elección malvada o mala para mí :)

@yyx990803 ¿planea que el estilo <MyComponent> sea ​​el estilo promocionado (es decir, los documentos y ejemplos se escribirán así), o será solo una opción, y el estilo de kebab seguirá siendo el principal?

@ blake-newman, lea este comentario ; se ajusta al estándar :)

@paulpflug @guidobouman : ya hay advertencias para las etiquetas y atributos camelCase si está utilizando las últimas versiones de vue-loader o vueify . Sin embargo, las comprobaciones de camelCase deben realizarse en tiempo de compilación porque en tiempo de ejecución la información del caso ya se habría perdido debido al comportamiento del analizador HTML. Entonces, si está utilizando Vue sin vue-loader o vueify , no habrá (y no puede) ninguna advertencia.

@ yyx990803 - Pero, la especificación @blake-newman vinculada a los componentes web establece esto:

El tipo de elemento personalizado identifica una interfaz de elemento personalizado y es una secuencia de caracteres que debe coincidir con la producción de NCName, debe contener un carácter _U+002D GUIÓN- MENOS_ y _no debe contener ninguna letra ASCII mayúscula_ .

Simplemente no estoy muy seguro de cómo se relaciona eso con los componentes de Vue. En los documentos, usted dice que intenta seguir libremente el estándar de componentes web.

Es posible que haya notado que los componentes de Vue.js son muy similares a los elementos personalizados, que forman parte de la especificación de componentes web. De hecho, la sintaxis de los componentes de Vue.js se modela libremente según la especificación.

Entonces, yo diría que la especificación debe cambiar primero, para permitir camelCase y PascalCase.

scott

@smolinari, los documentos de Vue dicen que está 'modelado libremente', no 'estrictamente' y, en mi opinión, eso deja espacio para este cambio.

@yyx990803 la información del caso puede perderse, pero aún podría haber una advertencia.
Cuando escribí 'mycOmponent' en la plantilla, se analizará a mycomponent pero lo esperado es my-component luego Vue (en modo de depuración) debería buscar mycomponent además my-component y adviértame sobre el uso incorrecto. La información del caso perdido no importa aquí.
Podría haber una opción para suprimir la advertencia y hacer coincidir directamente (es igual a su comportamiento sugerido).

-1 para migrar a camelCase/PascalCase. Sería algo chocante ver una sintaxis similar a JS en HTML. La misma razón por la que no soporto jsx.
+1 a la sugerencia de @paulpflug . Si el problema es la incorporación de principiantes, ¿por qué no simplemente emitir una advertencia que informe al usuario del problema?

¡@paulpflug eso suena como una idea válida!

Estoy de acuerdo, tener una advertencia que diga 'mycomponent' is missing, did you mean 'my-component'? se siente mejor que una sustitución silenciosa.

@ yyx990803 ¿Es posible hacer esto en una API de opción global?
p.ej
Vue.config.kebab = true (por defecto) -> <my-component :my-prop="msg"></my-component>
Vue.config.kebab = false -> <MyComponent :myProp="msg"></MyComponent>

@yyx990803
solo me pregunto, ¿cuál es el ideal por el que estamos luchando?
como dijo @rpkilby , <MyComponent myCustomProp="myProp" data-name="prop" aria-label="Close" onclick="myDialog.close()"> se ve raro.

Esencialmente, el problema existe porque js y html son tecnologías diferentes y usan diferentes sistemas de nombres. Y usar el mismo caso (kebab o camello) en ambas tecnologías cambiará la rareza de un lugar a otro, pero el problema subyacente persistirá.
Así que creo que lo mejor que podemos hacer es trazar una línea. y la línea actual i,e. El caso de kebab en contexto html y camleCase (y PascalCase) en contexto js es muy bueno .

entonces, en mi opinión, deberíamos simplemente apoyar las convenciones actuales en lugar de buscar una mejor. Y, por supuesto, use la advertencia para ayudar a los principiantes.

@ prog-rajkamal sí, ahora me inclino a implementar la advertencia.

Ahora voto :+1: solo por agregar la advertencia también.

scott

:+1: para agregar una advertencia

:+1: por la advertencia también

Cerrado a través de ccf9bede6bc39fb62e43e1efe98136c5f35dae6b y d7b55c4ee8491dbd853e28a1527050d2d1e7deab

Una advertencia sería genial. Acabo de pasar una hora tratando de averiguar por qué no se respondió a mi evento personalizado (la respuesta es que tenía un nombre en mayúsculas y minúsculas).

Hay una advertencia cuando tiene un componente o accesorio correspondiente que respondería a la versión kebab-case de su componente o accesorio PascalCase . Si comete un error tipográfico en un evento, no hay mucho que Vue pueda hacer al respecto.

¿O te refieres a accesorios de eventos existentes predeterminados como v-on:keyup o @keyup en resumen?

@guidobouman en mi archivo de plantilla tenía <my-component v-on:customEvent="myMethod"> . En un componente secundario tenía this.$emit('customEvent'); . El evento real que está escuchando el padre es customevent no customEvent , por supuesto, pero me tomó mucho tiempo darme cuenta porque no es fácil de depurar. Estaba pensando que hubiera sido bueno advertir que un atributo de caso de camello no se analizaría como tal, para personas olvidadizas como yo. Tal vez esto ya se haya discutido anteriormente, y si es así, pido disculpas.

@anthonygore lamentablemente es imposible, porque el navegador convierte html a minúsculas antes de que Vue tenga la oportunidad de acceder a él.

Mi pregunta es, ¿por qué Vue no puede convertirlo por nosotros? ¿Por qué tenemos que recordar sobre kebab-case en

La única regla para memorizar: HTML = kebab-case, JavaScript = camelCase

Por HTML me refiero a atributos y etiquetas. Los valores de atributo son expresiones de JavaScript cuando usa v-bind , por lo que se aplica la segunda declaración.

Mi pregunta es, ¿por qué Vue no puede convertirlo por nosotros? ¿Por qué tenemos que recordar sobre kebab-case en archivos in vue? Hace que las cosas sean más incómodas para los principiantes... Acabo de perder los últimos 20 minutos para eso...

desperdicié la última hora y media porque no solo lo busqué en Google... dxmn

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

robertleeplummerjr picture robertleeplummerjr  ·  3Comentarios

aviggngyv picture aviggngyv  ·  3Comentarios

gkiely picture gkiely  ·  3Comentarios

seemsindie picture seemsindie  ·  3Comentarios

hiendv picture hiendv  ·  3Comentarios