Vue: Solução alternativa de distinção entre maiúsculas e minúsculas HTML

Criado em 6 fev. 2016  ·  48Comentários  ·  Fonte: vuejs/vue

O problema

Então, como todos sabemos, o HTML não diferencia maiúsculas de minúsculas. myProp="123" é analisado como myprop="123" e isso levou à advertência no Vue.js onde você tem que usar my-prop="123" para se referir a um prop declarado em JavaScript como myProp . Isso morde os iniciantes com bastante frequência.

Além disso, também precisamos aplicar o mesmo mapeamento a componentes personalizados - por exemplo, quando você define um componente:

import MyComponent from './my-component'

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

Você deve usar <my-component> no modelo em vez de <MyComponent> .

A parte chata aqui é porque o Vue.js depende do navegador para pré-analisar os templates, quando o Vue.js consegue compilá-lo, as informações do caso já estão perdidas.

A ideia

E se ajustarmos a lógica de correspondência para que as coisas funcionem? Por exemplo, tornando isso possível:

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

Por quê?

Além de eliminar a inconsistência camelCase vs kebab-case em nosso código, existem algumas razões práticas pelas quais preferimos PascalCase/camelCase para componentes e adereços:

  1. Props precisam ser referenciados em templates e JavaScript como propriedades. Ter hífens neles torna muito estranho. ( myProp vs. this['my-prop'] )
  2. Quando importamos outro componente, o nome da variável não pode ser kebab case. por exemplo, você pode fazer import MyComp from './my-comp' mas my-comp simplesmente não é um nome de variável válido. E com a abreviação literal de objeto ES2015, você pode simplesmente fazer components: { MyComp } .
  3. Os nomes dos componentes em maiúsculas se destacam mais em relação aos elementos regulares, tornando mais claro quais tags são componentes personalizados e quais tags não são.

Detalhes técnicos

A implementação subjacente é que quando processamos as props e as opções de componentes, nós as normalizamos em minúsculas. Dessa forma, eles simplesmente se tornam mycomponent e myprop durante o processo de correspondência interna, mas você ainda pode usar o caso desejado no código do seu aplicativo. (Na verdade, os usuários nem precisam saber sobre esses componentes internos)

Possíveis preocupações:

  1. Compatibilidade com versões anteriores. A conversão de minúsculas pode ser feita junto com a conversão atual de kebab-case, para que ambas as sintaxes possam coexistir, nada será interrompido.
  2. myProp e MyProp serão tratados como a mesma coisa no modelo. No entanto, não faz sentido ter dois adereços ou dois componentes no mesmo componente diferenciados apenas por caso, e podemos facilmente detectar e alertar contra tal uso.
  3. Devemos aplicar a mesma regra a eventos personalizados também? Por exemplo:

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

Isso basicamente significa que os nomes de eventos não diferenciam maiúsculas de minúsculas, o que tem uma implicação maior do que props e nomes de componentes porque isso afeta o uso do sistema de eventos em javascript puro. Faz sentido normalizar todos os nomes de eventos em letras minúsculas? Novamente, parece raro ter dois eventos diferenciados apenas por caso (por exemplo, ter myEvent e myevent no mesmo aplicativo que fazem coisas diferentes), mas eu quero obter feedback sobre isso.

discussion

Comentários muito úteis

A única regra para memorizar: HTML = kebab-case, JavaScript = camelCase

Por HTML quero dizer atributos e tags. Os valores de atributo são expressões JavaScript quando você usa v-bind , portanto, a segunda instrução se aplica.

Todos 48 comentários

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

+
Muitas vezes eu quero escrever dessa maneira para ver a diferença entre os componentes e as tags

+1

Faz sentido normalizar todos os nomes de eventos em letras minúsculas?

Sim! Faz sentido, porque torna o código mais legível. Eu sempre mantenho os nomes dos eventos em minúsculas, separo-os por traço, em vez de camelcase. Acho que adicionar aviso para nomes de eventos camelcase também seria bom.

Isso significa que o Vuejs estará se afastando da especificação HTML seguindo uma abordagem semelhante como Angular ?

Existe alguma preocupação de desempenho?

Alguns pensamentos sobre as possíveis preocupações:

  1. Enquanto houver compatibilidade com versões anteriores, ficarei tranquilo com o que for decidido, mas provavelmente continuarei usando o método kebab case
  2. A falta de distinção entre caixa de camelo e caixa de camelo inferior pode ser confusa para alguns. De um modo geral var CamelCase se referiria a uma classe e var camelCase se referiria a uma variável não-classe, var camelCase = new CamelCase(); . Mas, eu não acho que isso seria um problema, porque você não gostaria de criar classes com o nome de seus componentes.
  3. Eu concordaria que criar dois eventos únicos apenas diferenciados pelo caso seria uma programação muito ruim.

Minha maior preocupação é introduzir inconsistências estranhas na forma como as pessoas codificam. Por exemplo, todos eles são válidos e idênticos: :myprop="" :myProp="" :mYpRoP="" :my-prop="" .

👎 Mantenha kebab-case na marcação e camel case no código. Faz parte da especificação HTML e ignorar o caso será uma curva de aprendizado maior para quem vem de outros frameworks ou que já aprendeu o padrão.

Eu concordo com @Teevio , a consistência será perdida

HTML usa kebab-case e é um padrão aceito pela comunidade que ECMAScript é uma linguagem camelCase. Devemos mantê-los separados em vez de _hiding_ (em reagir, a única maneira de reagir para renderizar o atributo personalizado é via data-* & aria-*, que impõe consistência).

Explicar por que (digamos via link MDN ou mesmo aqui) camelCase <-> kebab-case para um _iniciante_ ajudará muito o entendimento de HTML do iniciante.

Concordo com Evan, legibilidade e consistência de código são mais importantes!
+1

Para mim vai parecer muito estranho ter camelCase dentro do HTML.

HTML é HTML, JS é JS

a versão atual está boa

Tendo usado o Vue por 6 meses, isso - ainda me pega toda vez :( não é grande coisa, pois o aviso para o Vue é tão bom que eu sei o que fiz, mas posso entender completamente a ideia aqui e apoiá-la +1

+1 Compatibilidade com versões anteriores também.

+1
Eu concordei. precisamos manter a compatibilidade com versões anteriores.

Faz sentido normalizar todos os nomes de eventos em letras minúsculas?

Concordo com @azamat-sharapov

Os componentes do @Teevio Vue são aproximadamente classes: quando você faz var MyComp = Vue.extend({ .. }) você pode fazer var myComp = new MyComp() . Quanto ao problema de múltiplas sintaxes válidas, ele já existe: :my-prop , :MY-PROP e :mY-pRop todos funcionam da mesma forma a partir de agora, porque o HTML simplesmente joga fora todas as informações do caso. Não é muito diferente com o recurso proposto. Como em todos os argumentos de estilo, trata-se de escolher um estilo e mantê-lo.

Re @jamesxv7 @moe-szyslak @jonagoldman e outros que se preocupam em se afastar do padrão HTML: é totalmente válido escrever tags/atributos camelCase em HTML, é apenas a correspondência de nome de tag/atributo que será realizada sem distinção entre maiúsculas e minúsculas . Isto é o que diz a especificação :

Em documentos na sintaxe HTML:

Nomes de tags para elementos HTML podem ser escritos com qualquer combinação de letras minúsculas e maiúsculas que não façam distinção entre maiúsculas e minúsculas para os nomes dos elementos fornecidos na seção de elementos HTML deste documento; ou seja, os nomes das tags não diferenciam maiúsculas de minúsculas.
Os nomes de atributos para elementos HTML podem ser escritos com qualquer combinação de letras minúsculas e maiúsculas que não façam distinção entre maiúsculas e minúsculas para os nomes dos atributos fornecidos na seção de elementos HTML deste documento; ou seja, os nomes dos atributos não diferenciam maiúsculas de minúsculas.

Portanto, se o uso do PascalCase/camelCase melhora a consistência/legibilidade do código, é totalmente compatível com as especificações. Isso pode não ser para todos, mas se você preferir a caixa de kebab, pode continuar usando isso.

E em particular, re @jamesxv7 : isso é diferente do que o Angular 2 está fazendo. Angular 2 está tornando seus modelos sensíveis a maiúsculas e minúsculas, introduzindo um analisador HTML personalizado. Pelo contrário, o Vue realmente segue a especificação, tornando as contrapartes JS insensíveis a maiúsculas e minúsculas.

Eu prefiro manter kebab em html. Gosto da ideia de consistência, mas gosto mais da ideia de conformidade com as especificações.

Etiqueta camelCase encontrada:. HTML não diferencia maiúsculas de minúsculas. Usarem vez de. O Vue irá combiná-lo automaticamente com os componentes definidos com ids camelCase em JavaScript.

Este aviso já é bastante conciso sobre como funciona o registro de componentes. Dito isto, como outros já mencionaram, acho que permitir camelCase em HTML é ótimo, desde que ainda haja a opção de continuar escrevendo kebab.

@yyx990803 sim , concordo. Apenas tentando pensar em tantos argumentos quanto eu pudesse contra isso, mas honestamente eu não tenho nenhum que valha a pena. Como você mencionou, no final do dia estamos discutindo escolhas estilísticas. Pessoalmente, acho que, desde que possamos manter o que já temos, tendo a opção de usar as coisas novas (mas não forçadas), estou bem com as mudanças mencionadas.

Se o kebab-case ainda funcionar e usar camelCase/PascalCase for uma opção que não quebra BC, quando eu os uso, não posso ser contra a adição. Não é uma mudança que me obriga a fazer algo diferente. É apenas uma nova opção.

A única coisa que eu poderia dizer ou sugerir é que essa opção esteja bem documentada e - Bom trabalho, como sempre Evan!

Scott

Talvez possamos fazer uma opção: avisar ou ignorar.
Digamos que eu tenha um componente: myComponent
e eu me refiro a ele em html como mycompOnent Eu pessoalmente preferiria um aviso, como:
we found something that would match "myComponent": "mycompOnent" (line 152), use "my-component" instead
O mesmo para os adereços, é claro.
Acho que a legibilidade posterior é mais importante do que qualquer coisa funcionando na primeira tentativa.

Eu também me deparei com problemas kebab-case/camelCase. Mas o verdadeiro problema foi que não recebi nenhum aviso do que estava errado;)

O padrão pode ser que não haja aviso e simplesmente funcione, isso é irrelevante para mim.
Além disso, os avisos devem ser visíveis apenas no modo de depuração, eu acho

E coisas como atone vs a-tone vs at-one ? Imagino que sejam ocorrências bastante raras.

Os adereços de caso de kebab @simplesmiler ainda seriam combinados com a diferenciação de maiúsculas e minúsculas usando regras antigas.

Isso não promove transparência aos padrões da web. A especificação de elementos personalizados afirma que os nomes devem conter um hífen: <my-component/>

E o que @simplesmiler disse: addOne e adDone executariam o mesmo código. Isso seria especialmente desagradável para a implementação de eventos,

E como o html não diferencia maiúsculas de minúsculas, não vamos introduzir a ideia de maiúsculas e minúsculas da biblioteca. Essa implementação só promoveria o case em html, o que na minha opinião é uma má ideia.

Além disso, usamos a separação por hífen nos nomes dos arquivos. Devemos removê-los lá também e começar a adicionar o revestimento?

Por último: a coexistência do sistema hypen & casing promove diferentes estilos de codificação para novos desenvolvedores em uma equipe.

Eu prefiro a abordagem do @paulpflug ; Avisos adequados nesta área ajudariam muito.

Eu não sou um fã de fazer o caso HTML Pascal/Camel. Ele quebra os padrões da web, eu sei que é bom manter a consistência.

Ao tentar tornar as coisas minimamente consistentes, você adiciona outra camada de complexidade. Também pode estar atraindo más práticas. Uma biblioteca deve promover a permanência nos padrões e não enganar os desenvolvedores, pois um dia eles podem ter que trabalhar em um local que não usa Vue, resultando em não entender por que o HTML está sendo analisado de forma diferente.

Eu concordo totalmente com @paulpflug : Adicionar um aviso significa menos trabalho para o código de produção e coloca os desenvolvedores de volta no caminho certo para escrever um código válido.

Um bom argumento sobre por que isso não deve ser implementado: http://eisenbergeffect.bluespire.com/on-angular-2-and-html/

Esta é geralmente uma razão destacada pela qual as pessoas não gostam do Angular 2. Eu concordo totalmente em manter as bibliotecas em conformidade com os padrões. Ele já foi elaborado para que o HTML diferenciasse maiúsculas de minúsculas e foi descartado por causa de muitos problemas e abertura de situações de muita flexibilidade.

@blake-newman: Sobre isso , acho que @yyx990803 já falou sobre isso em um comentário anterior.

@jamesxv7 Esse comentário resume muito bem; Evan não está propondo mudar as especificações do HTML, ele está propondo mudar como o Vue localiza os nomes dos componentes. Em vez de converter kebab em camelo e encontrar o componente correspondente, provavelmente removeria os traços (para acomodar o kebab) e, em seguida, procuraria componentes sem distinção entre maiúsculas e minúsculas. O próprio HTML continuará a ser compatível com as especificações. Também nos permitiria usar o caso que quisermos. Isso não parece uma escolha má ou ruim para mim :)

@yyx990803 você planeja que o estilo <MyComponent> seja o estilo promovido (ou seja, documentos e exemplos serão escritos assim), ou será apenas uma opção, e o estilo kebab-case continuará sendo o principal?

@blake-newman leia este comentário - ele está em conformidade com o padrão :)

@paulpflug @guidobouman : já existem avisos para tags e atributos camelCase se você estiver usando as versões mais recentes de vue-loader ou vueify . No entanto, as verificações do camelCase devem ser executadas em tempo de compilação porque em tempo de execução as informações do caso já teriam sido perdidas devido ao comportamento do analisador HTML. Portanto, se você estiver usando o Vue sem vue-loader ou vueify , não haverá (e não pode) haver nenhum aviso.

@yyx990803 - Mas, a especificação @blake-newman vinculada aos componentes da Web declara isso:

O tipo de elemento personalizado identifica uma interface de elemento personalizado e é uma sequência de caracteres que deve corresponder à produção de NCName, deve conter um caractere _U+002D HYPHEN-MINUS_ e _não deve conter nenhuma letra ASCII maiúscula_ .

Só não tenho certeza de como isso se relaciona aos componentes do Vue. Nos documentos, você diz que tenta seguir vagamente o padrão de componentes da web.

Você deve ter notado que os componentes do Vue.js são muito semelhantes aos Elementos Personalizados, que fazem parte da Especificação de Componentes da Web. Na verdade, a sintaxe do componente Vue.js é modelada livremente após a especificação.

Então, eu diria que a especificação precisa mudar primeiro, para permitir camelCase e PascalCase.

Scott

@smolinari os documentos do Vue dizem que é 'modelado livremente' e não 'estritamente' e na minha mente isso deixa espaço para essa mudança.

@yyx990803 as informações do caso podem ser perdidas, mas ainda pode haver um aviso.
Quando eu escrevi 'mycOmponent' no modelo, ele será analisado para mycomponent mas o esperado é my-component , então o Vue (no modo de depuração) deve procurar mycomponent além my-component e me avise sobre o uso errado. As informações do caso perdido não importam aqui.
Pode haver uma opção para suprimir o aviso e corresponder diretamente (igual ao seu comportamento sugerido).

-1 para migrar para camelCase/PascalCase. Seria um pouco chocante ver a sintaxe do tipo JS em HTML. Mesma razão pela qual eu não suporto jsx.
+1 para a sugestão de @paulpflug . Se o problema for a integração de iniciantes, por que não apenas emitir um aviso informando o usuário sobre o problema?

@paulpflug isso soa como uma ideia válida!

Concordo, ter um aviso que diz 'mycomponent' is missing, did you mean 'my-component'? é melhor do que a substituição silenciosa.

@ yyx990803 É possível fazer isso em uma API de opção global?
por exemplo
Vue.config.kebab = true (por padrão) -> <my-component :my-prop="msg"></my-component>
Vue.config.kebab = false -> <MyComponent :myProp="msg"></MyComponent>

@yyx990803
apenas me perguntando, qual é o ideal pelo qual estamos lutando?
como @rpkilby disse, <MyComponent myCustomProp="myProp" data-name="prop" aria-label="Close" onclick="myDialog.close()"> parece estranho.

Essencialmente, o problema existe porque js e html são tecnologias diferentes e usam sistemas de nomenclatura diferentes. E usar o mesmo caso (kebab ou camelo) em ambas as tecnologias mudará a estranheza de um lugar para outro, mas o problema subjacente persistirá
Então eu acredito que o melhor que podemos fazer é traçar uma linha. e a linha atual i,e. kebab case em contexto html e camleCase (e PascalCase) em contexto js é muito bom .

então IMO, devemos apenas apoiar as convenções atuais em vez de procurar uma melhor. E claro, use o aviso para ajudar os iniciantes

@prog-rajkamal sim, agora estou inclinado a apenas implementar o aviso.

Eu agora voto :+1: em apenas adicionar o aviso também.

Scott

:+1: para adicionar um aviso

:+1: pelo aviso também

Fechado via ccf9bede6bc39fb62e43e1efe98136c5f35dae6b & d7b55c4ee8491dbd853e28a1527050d2d1e7deab

Um aviso seria ótimo. Acabei de passar uma hora tentando descobrir por que meu evento personalizado não foi respondido (a resposta é que ele tinha um nome em caixa de camelo).

Há um aviso quando você tem um componente ou prop correspondente que responderia à versão kebab-case do seu componente ou prop PascalCase . Se você cometer um erro de digitação em um evento, não há muito que o Vue possa fazer sobre isso.

Ou você quer dizer para adereços de eventos padrão existentes como v-on:keyup ou @keyup em resumo?

@guidobouman no meu arquivo de modelo eu tinha <my-component v-on:customEvent="myMethod"> . Em um componente filho eu tinha this.$emit('customEvent'); . O evento real que está sendo ouvido pelo pai é customevent não customEvent , é claro, mas levei séculos para descobrir isso porque não é fácil de depurar. Eu estava pensando que seria bom avisar que um atributo camel case não seria analisado como tal, para pessoas esquecidas como eu. Talvez isso já tenha sido discutido acima e, se sim, peço desculpas.

@anthonygore infelizmente é impossível, porque o navegador converte html para minúsculo antes que o Vue tenha a chance de acessá-lo.

Minha pergunta é, por que o Vue não pode convertê-lo para nós? Por que temos que lembrar sobre o caso de kebab em

A única regra para memorizar: HTML = kebab-case, JavaScript = camelCase

Por HTML quero dizer atributos e tags. Os valores de atributo são expressões JavaScript quando você usa v-bind , portanto, a segunda instrução se aplica.

Minha pergunta é, por que o Vue não pode convertê-lo para nós? Por que temos que lembrar sobre kebab-case nos arquivos vue? Isso torna as coisas mais estranhas para iniciantes... Eu perdi os últimos 20 minutos para isso...

desperdiçou a última 1,5 hora porque eu não apenas pesquisei no Google ... dxmn

Esta página foi útil?
0 / 5 - 0 avaliações