Vue: Solution de contournement HTML sensible à la casse

Créé le 6 févr. 2016  ·  48Commentaires  ·  Source: vuejs/vue

Le problème

Donc, comme nous le savons tous, HTML est insensible à la casse. myProp="123" est analysé comme myprop="123" et cela a conduit à la mise en garde dans Vue.js où vous devez utiliser my-prop="123" pour faire référence à un accessoire déclaré en JavaScript comme myProp . Cela mord assez souvent les débutants.

De plus, nous devons également appliquer le même mappage aux composants personnalisés - par exemple lorsque vous définissez un composant :

import MyComponent from './my-component'

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

Vous devez utiliser <my-component> dans le modèle au lieu de <MyComponent> .

La partie ennuyeuse ici est que Vue.js s'appuie sur le navigateur pour pré-analyser les modèles, au moment où Vue.js arrive à le compiler, les informations de cas sont déjà perdues.

L'idée

Et si nous ajustions la logique de correspondance pour que les choses fonctionnent ? Par exemple, rendre cela possible :

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

Pourquoi?

En plus d'éliminer l'incohérence camelCase vs kebab-case dans notre code, il y a quelques raisons pratiques pour lesquelles nous préférerions PascalCase/camelCase pour les composants et les accessoires :

  1. Les accessoires doivent être référencés dans les modèles et JavaScript en tant que propriétés. Avoir des traits d'union en eux rend cela très gênant. ( myProp contre this['my-prop'] )
  2. Lorsque nous importons un autre composant, le nom de la variable ne peut pas être kebab case. Par exemple, vous pouvez faire import MyComp from './my-comp' mais my-comp n'est tout simplement pas un nom de variable valide. Et avec le raccourci littéral d'objet ES2015, vous pouvez simplement faire components: { MyComp } .
  3. Les noms de composants en majuscules se démarquent davantage par rapport aux éléments normaux, ce qui permet de savoir plus clairement quelles balises sont des composants personnalisés et quelles balises ne le sont pas.

Détails techniques

L'implémentation sous-jacente est que lorsque nous traitons les options d'accessoires et de composants, nous les normalisons en minuscules. De cette façon, ils deviennent simplement mycomponent et myprop lors du processus de correspondance interne, mais vous pouvez toujours utiliser la casse souhaitée dans le code de votre application. (En fait, les utilisateurs n'ont même pas besoin de connaître ces composants internes)

Problèmes potentiels :

  1. Rétrocompatibilité. La conversion en minuscules peut être effectuée parallèlement à la conversion actuelle en cas de kebab, de sorte que les deux syntaxes peuvent coexister, rien ne se cassera.
  2. myProp et MyProp seront traités comme la même chose dans le modèle. Cependant, cela n'a aucun sens d'avoir deux accessoires ou deux composants dans le même composant différenciés uniquement par cas, et nous pouvons facilement détecter et avertir contre une telle utilisation.
  3. Devrions-nous également appliquer la même règle aux événements personnalisés ? Par example:

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

Cela signifie essentiellement que les noms d'événements deviennent insensibles à la casse, ce qui a une plus grande implication que les accessoires et les noms de composants, car cela affecte l'utilisation du système d'événements en javascript pur. Est-il judicieux de normaliser tous les noms d'événements en minuscules ? Encore une fois, il semble rare d'avoir deux événements différenciés uniquement par cas (par exemple, avoir à la fois myEvent et myevent dans la même application qui font des choses différentes), mais je veux obtenir des commentaires à ce sujet.

discussion

Commentaire le plus utile

La seule règle à mémoriser : HTML = kebab-case, JavaScript = camelCase

Par HTML, j'entends les attributs et les balises. Les valeurs d'attribut sont des expressions JavaScript lorsque vous utilisez v-bind , donc la deuxième instruction s'applique.

Tous les 48 commentaires

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

+
Je veux souvent écrire de cette façon pour voir la différence entre les composants et les balises

+1

Est-il judicieux de normaliser tous les noms d'événements en minuscules ?

Oui! Cela a du sens, car cela rend le code plus lisible. Je garde toujours les noms d'événements en minuscules, les sépare par un tiret, au lieu de camelcase. Je pense que l'ajout d'un avertissement pour les noms d'événements camelcase serait également bon.

Cela signifie-t-il que Vuejs s'éloignera de la spécification HTML poursuivant une approche similaire à Angular ?

Y a-t-il un problème de performances ?

Quelques réflexions sur les problèmes potentiels :

  1. Tant que la rétrocompatibilité existe, je serai cool avec tout ce qui sera finalement décidé, mais je continuerai probablement à utiliser la méthode de l'étui kebab
  2. Le manque de distinction entre camel-case et camel-case inférieur pourrait être source de confusion pour certains. De manière générale, var CamelCase ferait référence à une classe et var camelCase ferait référence à une variable non-classe, var camelCase = new CamelCase(); . Mais je ne pense pas que ce serait un problème, car vous ne voudriez pas créer des classes nommées d'après vos composants.
  3. Je serais d'accord que créer deux événements uniques ne se distinguant que par le cas serait une très mauvaise programmation.

Ma plus grande préoccupation est d'introduire des incohérences étranges dans la façon dont les gens codent. Par exemple, tous ces éléments sont valides et identiques : :myprop="" :myProp="" :mYpRoP="" :my-prop="" .

👎 Gardez kebab-case dans le balisage et camel case dans le code. Cela fait partie de la spécification HTML et ignorer la casse sera une plus grande courbe d'apprentissage pour ceux qui viennent d'autres frameworks ou qui ont déjà appris la norme.

Je suis d'accord avec @Teevio , la cohérence sera perdue

HTML utilise kebab-case et c'est une norme communautaire acceptée selon laquelle ECMAScript est un langage camelCase. Nous devrions les garder séparés au lieu de _hiding_ (En réaction, la seule façon de réagir pour rendre l'attribut personnalisé est via data-* & aria-*, qui renforce la cohérence).

Expliquer pourquoi (par exemple via le lien MDN ou même ici) camelCase <-> kebab-case à un _débutant_ aidera grandement la compréhension HTML du débutant.

D'accord avec Evan, la lisibilité et la cohérence du code sont plus importantes !
+1

Pour moi, cela semblera vraiment bizarre d'avoir camelCase dans HTML.

HTML est HTML, JS est JS

la version actuelle est très bien

Ayant utilisé Vue pendant 6 mois, cela me préoccupe toujours à chaque fois :( ce n'est pas grave car les avertissements pour Vue sont si bons que je sais ce que j'ai fait, mais je peux parfaitement comprendre l'idée ici et la soutenir +1

+1 Rétrocompatibilité aussi.

+1
J'ai été d'accord. nous devons garder la rétrocompatibilité.

Est-il judicieux de normaliser tous les noms d'événements en minuscules ?

Je suis d'accord avec @azamat-sharapov

Les composants @Teevio Vue sont à peu près des classes : quand vous faites var MyComp = Vue.extend({ .. }) vous pouvez alors faire var myComp = new MyComp() . Quant au problème de syntaxe valide multiple, il existe déjà : :my-prop , :MY-PROP et :mY-pRop fonctionnent tous de la même manière à partir de maintenant, car HTML jette simplement toutes les informations de cas. Ce n'est pas très différent avec la fonctionnalité proposée. Comme pour tous les arguments de style, il s'agit de choisir un style et de s'y tenir.

Re @jamesxv7 @moe-szyslak @jonagoldman et d'autres qui s'inquiètent de s'éloigner de la norme HTML : il est tout à fait valide d'écrire des balises/attributs camelCase en HTML, c'est juste que la correspondance des noms de balises/attributs sera effectuée d'une manière insensible à la casse . Voici ce que dit la spécification :

Dans les documents en syntaxe HTML :

Les noms de balises pour les éléments HTML peuvent être écrits avec n'importe quel mélange de lettres minuscules et majuscules qui ne respectent pas la casse pour les noms des éléments donnés dans la section des éléments HTML de ce document ; c'est-à-dire que les noms de balise ne sont pas sensibles à la casse.
Les noms d'attributs pour les éléments HTML peuvent être écrits avec n'importe quel mélange de lettres minuscules et majuscules qui ne respectent pas la casse pour les noms des attributs donnés dans la section des éléments HTML de ce document ; c'est-à-dire que les noms d'attribut ne sont pas sensibles à la casse.

Donc, si l'utilisation de PascalCase/camelCase améliore la cohérence/lisibilité du code, il est totalement conforme aux spécifications de le faire. Ce n'est peut-être pas pour tout le monde, mais si vous préférez l'étui à kebab, vous pouvez continuer à l'utiliser.

Et en particulier, re @jamesxv7 : c'est différent de ce que fait Angular 2. Angular 2 rend ses modèles sensibles à la casse en introduisant un analyseur HTML personnalisé. Au contraire, Vue suit la spécification en rendant les homologues JS insensibles à la casse.

Je préfère garder kebab en html. J'aime l'idée de cohérence, mais j'aime davantage l'idée de conformité aux spécifications.

Balise camelCase trouvée :. HTML est insensible à la casse. Utiliserplutôt. Vue le comparera automatiquement aux composants définis avec les identifiants camelCase en JavaScript.

Cet avertissement est déjà assez concis sur le fonctionnement de l'enregistrement des composants. Cela dit, comme d'autres l'ont mentionné, je pense que l'autorisation de camelCase en HTML est excellente, tant qu'il reste la possibilité de continuer à écrire kebab.

@ yyx990803 yah, d'accord. J'essaie juste de trouver autant d'arguments que possible contre cela, mais honnêtement, je n'en ai aucun qui collerait. Comme vous l'avez mentionné, en fin de compte, nous discutons des choix stylistiques. Personnellement, je pense que tant que nous pouvons nous en tenir à ce que nous avons déjà tout en ayant la possibilité d'utiliser les nouveaux éléments (mais pas obligés), je suis d'accord avec les changements mentionnés.

Si kebab-case fonctionne toujours et que l'utilisation de camelCase/ PascalCase est une option qui ne casse pas BC, lorsque je les utilise, je ne peux pas être contre l'ajout. Ce n'est pas un changement qui m'oblige à faire quelque chose de différent. C'est juste une nouvelle option.

La seule chose que je pourrais dire ou suggérer est de s'assurer que cette option est bien documentée et - Bon travail, comme toujours Evan !

Scott

Peut-être pouvons-nous en faire une option : avertir ou ignorer.
Disons que j'ai un composant : myComponent
et je m'y réfère en html comme mycompOnent Je préférerais personnellement un avertissement, comme :
we found something that would match "myComponent": "mycompOnent" (line 152), use "my-component" instead
Pareil pour les accessoires bien sûr.
Je pense que la lisibilité ultérieure est plus importante que tout ce qui fonctionne du premier coup.

Je suis également tombé sur des problèmes de kebab-case/camelCase. Mais le vrai problème était que je n'avais aucun avertissement sur ce qui n'allait pas ;)

La valeur par défaut pourrait être qu'il n'y a pas d'avertissement et que cela fonctionne, ce n'est pas pertinent pour moi.
De plus, les avertissements ne devraient être visibles qu'en mode débogage, je pense

Qu'en est-il des choses comme atone vs a-tone vs at-one ? J'imagine que ce sont des événements assez rares cependant.

Les accessoires de cas de kebab @simplesmiler seraient toujours associés à la sensibilité à la casse en utilisant les anciennes règles.

Cela ne favorise pas la transparence vis-à-vis des standards du Web. La spécification des éléments personnalisés indique que les noms doivent contenir un trait d'union : <my-component/>

Qu'en est-il de ce que @simplesmiler a dit : addOne et adDone exécuteraient le même code. Ce serait particulièrement désagréable pour la mise en place d'événements,

Et parce que html est insensible à la casse, n'introduisons pas l'idée de casse de la bibliothèque. Cette implémentation ne ferait que promouvoir la casse en html, ce qui à mon avis est une mauvaise idée.

De plus, nous utilisons la séparation par trait d'union dans les noms de fichiers. Devrions-nous également les supprimer et commencer à ajouter du boîtier ?

Enfin : la coexistence du système de trait d'union et de casse favorise différents styles de codage pour les nouveaux développeurs d'une équipe.

Je préfère l'approche de @paulpflug ; Des avertissements appropriés dans ce domaine aideraient beaucoup.

Je ne suis pas fan de faire le cas HTML Pascal/Camel. Ça casse les standards du web, je sais que c'est bien de garder la cohérence.

En essayant de rendre les choses le moins du monde cohérentes, vous ajoutez une autre couche de complexité. Il peut également s'agir de mauvaises pratiques alléchantes. Une bibliothèque doit promouvoir le respect des normes et ne pas induire les développeurs en erreur, car un jour ils devront peut-être travailler dans un endroit n'utilisant pas Vue, ce qui les empêchera de comprendre pourquoi le HTML est analysé différemment.

Je suis totalement d'accord avec @paulpflug : Ajouter un avertissement signifie moins de travail pour le code de production et remet les développeurs sur la bonne voie pour écrire du code valide.

Un bon argument pour expliquer pourquoi cela ne devrait pas être implémenté : http://eisenbergeffect.bluespire.com/on-angular-2-and-html/

C'est généralement une raison pour laquelle les gens n'aiment pas Angular 2. Je suis totalement d'accord pour que les bibliothèques restent conformes aux normes. Il a été une fois rédigé pour que le HTML soit sensible à la casse, et il a été rejeté en raison de trop de problèmes et d'ouverture de situations trop flexibles.

@blake-newman : Concernant ça , je pense que @yyx990803 en a déjà parlé dans un précédent commentaire .

@ jamesxv7 Ce commentaire résume assez bien; Evan ne propose pas de modifier les spécifications HTML, il propose de modifier la façon dont Vue localise les noms de composants. Plutôt que de convertir kebab en chameau et de trouver le composant correspondant, il supprimerait probablement les tirets (pour s'adapter au kebab), puis rechercherait des composants sans sensibilité à la casse. Le code HTML lui-même continuera d'être conforme aux spécifications. Cela nous permettrait également d'utiliser n'importe quel cas que nous voulons. Cela ne me semble pas un mauvais choix ou un mauvais choix :)

@ yyx990803 prévoyez -vous que le style <MyComponent> soit le style promu (c'est-à-dire que les documents et les exemples seront écrits comme ceci), ou ce ne sera qu'une option, et le style kebab-case restera le principal ?

@blake-newman lisez ce commentaire - il est conforme à la norme :)

@paulpflug @guidobouman : il y a déjà des avertissements pour les balises et attributs camelCase si vous utilisez les dernières versions de vue-loader ou vueify . Cependant, les vérifications camelCase doivent être effectuées au moment de la compilation car lors de l'exécution, les informations de cas auraient déjà été perdues en raison du comportement de l'analyseur HTML. Donc, si vous utilisez Vue sans vue-loader ou vueify , il n'y aura pas (et ne peut pas) y avoir d'avertissements.

@ yyx990803 - Mais, la spécification @blake-newman liée aux composants Web indique ceci :

Le type d'élément personnalisé identifie une interface d'élément personnalisée et est une séquence de caractères qui doit correspondre à la production NCName, doit contenir un caractère _U+002D HYPHEN-MINUS_ et _ne doit pas contenir de lettres ASCII majuscules_ .

Je ne sais pas trop comment cela se rapporte aux composants Vue. Dans la documentation, vous dites que vous essayez de suivre vaguement la norme des composants Web.

Vous avez peut-être remarqué que les composants Vue.js sont très similaires aux éléments personnalisés, qui font partie de la spécification des composants Web. En fait, la syntaxe des composants de Vue.js est vaguement modélisée d'après la spécification.

Donc, je dirais que la spécification doit d'abord changer, afin d'autoriser camelCase et PascalCase.

Scott

@smolinari les docs de Vue disent qu'il est "modélisé de manière lâche" et non "strictement" et dans mon esprit, cela laisse de la place pour ce changement.

@ yyx990803 les informations sur le cas peuvent être perdues, mais il peut toujours y avoir un avertissement.
Lorsque j'ai écrit 'mycOmponent' dans le modèle, il sera analysé en mycomponent mais attendu est my-component alors Vue (en mode débogage) devrait rechercher mycomponent en plus my-component et avertissez-moi de la mauvaise utilisation. Les informations sur les cas perdus n'ont pas d'importance ici.
Il pourrait y avoir une option pour supprimer l'avertissement et faire correspondre directement à la place (équivaut à votre comportement suggéré).

-1 pour migrer vers camelCase/PascalCase. Il serait quelque peu choquant de voir une syntaxe de type JS en HTML. Même raison pour laquelle je ne supporte pas jsx.
+1 à la suggestion de @paulpflug . Si le problème concerne l'intégration des débutants, pourquoi ne pas simplement émettre un avertissement informant l'utilisateur du problème ?

@paulpflug cela ressemble à une idée valable !

Je suis d'accord, avoir un avertissement qui dit 'mycomponent' is missing, did you mean 'my-component'? est plus agréable qu'une substitution silencieuse.

@ yyx990803 Est-il possible de le faire sur une API d'option globale ?
par exemple
Vue.config.kebab = true (par défaut) -> <my-component :my-prop="msg"></my-component>
Vue.config.kebab = false -> <MyComponent :myProp="msg"></MyComponent>

@yyx990803
je me demande simplement quel est l'idéal vers lequel nous nous efforçons?
comme @rpkilby l' a dit, <MyComponent myCustomProp="myProp" data-name="prop" aria-label="Close" onclick="myDialog.close()"> a l'air bizarre.

Essentiellement, le problème existe parce que js et html sont des technologies différentes et utilisent des systèmes de nommage différents. Et l'utilisation du même étui (kebab ou chameau) dans les deux technologies déplacera l'étrangeté d'un endroit à un autre, mais le problème sous-jacent persistera
Je pense donc que le mieux que nous puissions faire est de tracer une ligne. et la ligne courante i,e. kebab case en contexte html et camleCase (et PascalCase) en contexte js est très bon .

donc OMI, nous devrions simplement soutenir les conventions actuelles au lieu d'en chercher une meilleure. Et bien sûr, utilisez l'avertissement pour aider les débutants

@ prog-rajkamal ouais, je suis maintenant enclin à simplement mettre en œuvre l'avertissement.

Je vote maintenant :+1: pour simplement ajouter l'avertissement aussi.

Scott

:+1 : pour ajouter un avertissement

:+1: pour l'avertissement aussi

Fermé via ccf9bede6bc39fb62e43e1efe98136c5f35dae6b & d7b55c4ee8491dbd853e28a1527050d2d1e7deab

Un avertissement serait super. Je viens de passer une heure à essayer de comprendre pourquoi mon événement personnalisé n'a pas reçu de réponse (la réponse étant qu'il avait un nom en forme de chameau).

Un avertissement s'affiche lorsque vous avez un composant ou un accessoire correspondant qui répondrait à la version kebab-case de votre composant ou accessoire PascalCase . Si vous faites une faute de frappe dans un événement, Vue ne peut pas faire grand-chose à ce sujet.

Ou voulez-vous dire pour les accessoires d'événement existants par défaut comme v-on:keyup ou @keyup en bref ?

@guidobouman dans mon fichier modèle j'avais <my-component v-on:customEvent="myMethod"> . Dans un composant enfant, j'avais this.$emit('customEvent'); . L'événement réel écouté par le parent est customevent non customEvent , bien sûr, mais il m'a fallu une éternité pour comprendre cela car ce n'est pas facile à déboguer. Je pensais qu'il aurait été bon d'avertir qu'un attribut de cas de chameau ne serait pas analysé en tant que tel, pour les oublieux comme moi. Peut-être que cela a déjà été discuté ci-dessus, et si c'est le cas, je m'en excuse.

@anthonygore , malheureusement, c'est impossible, car le navigateur convertit le code HTML en minuscules avant que Vue n'ait la possibilité d'y accéder.

Ma question est la suivante : pourquoi Vue ne peut-il pas le convertir pour nous ? Pourquoi faut-il se souvenir du kebab-case dans

La seule règle à mémoriser : HTML = kebab-case, JavaScript = camelCase

Par HTML, j'entends les attributs et les balises. Les valeurs d'attribut sont des expressions JavaScript lorsque vous utilisez v-bind , donc la deuxième instruction s'applique.

Ma question est la suivante : pourquoi Vue ne peut-il pas le convertir pour nous ? Pourquoi devons-nous nous souvenir de kebab-case dans les fichiers in vue ? Cela rend les choses plus gênantes pour les débutants... J'ai juste perdu les 20 dernières minutes pour ça...

perdu la dernière heure et demie parce que je ne l'ai pas simplement cherché sur Google ... dxmn

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

seemsindie picture seemsindie  ·  3Commentaires

finico picture finico  ·  3Commentaires

lmnsg picture lmnsg  ·  3Commentaires

loki0609 picture loki0609  ·  3Commentaires

aviggngyv picture aviggngyv  ·  3Commentaires