Vue: Обходной путь чувствительности к регистру HTML

Созданный на 6 февр. 2016  ·  48Комментарии  ·  Источник: vuejs/vue

Проблема

Как мы все знаем, HTML нечувствителен к регистру. myProp="123" анализируется как myprop="123" , и это привело к оговорке в Vue.js, где вы должны использовать my-prop="123" для ссылки на свойство, объявленное в JavaScript как myProp . Это кусает новичков довольно часто.

Кроме того, нам также необходимо применить такое же сопоставление к пользовательским компонентам — например, когда вы определяете компонент:

import MyComponent from './my-component'

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

Вы должны использовать <my-component> в шаблоне вместо <MyComponent> .

Раздражает то, что Vue.js полагается на браузер для предварительного разбора шаблонов, и к тому времени, когда Vue.js скомпилирует его, информация о случае уже будет потеряна.

Идея

Что, если мы настроим логику сопоставления так, чтобы все просто работало? Например, сделать это возможным:

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

Почему?

В дополнение к устранению несоответствия между camelCase и kebab-case в нашем коде, есть несколько практических причин, по которым мы предпочли бы PascalCase/camelCase для компонентов и свойств:

  1. На реквизиты необходимо ссылаться в шаблонах и JavaScript как на свойства. Наличие дефисов в них делает его очень неудобным. ( myProp против this['my-prop'] )
  2. Когда мы импортируем другой компонент, имя переменной не может быть kebab case. Например, вы можете указать import MyComp from './my-comp' , но my-comp просто недопустимое имя переменной. А с помощью литерала объекта ES2015 вы можете просто сделать components: { MyComp } .
  3. Названия компонентов, написанные с заглавной буквы, выделяются больше, чем обычные элементы, что делает более понятным, какие теги являются пользовательскими компонентами, а какие нет.

Технические детали

Базовая реализация заключается в том, что когда мы обрабатываем реквизиты и параметры компонентов, мы нормализуем их в нижний регистр. Таким образом, они просто становятся mycomponent и myprop во время внутреннего процесса сопоставления, но вы все равно можете использовать нужный регистр в коде своего приложения. (На самом деле пользователям даже не нужно знать об этих внутренних компонентах)

Возможные опасения:

  1. Обратная совместимость. Преобразование нижнего регистра может быть выполнено вместе с текущим преобразованием регистра кебаба, поэтому оба синтаксиса могут сосуществовать, ничего не сломается.
  2. myProp и MyProp будут рассматриваться в шаблоне как одно и то же. Однако не имеет смысла иметь два реквизита или два компонента в одном компоненте, различающихся только регистром, и мы можем легко обнаружить такое использование и предупредить об этом.
  3. Должны ли мы применять то же правило и к пользовательским событиям? Например:

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

В основном это означает, что имена событий становятся нечувствительными к регистру, что имеет большее значение, чем имена свойств и компонентов, поскольку это влияет на использование системы событий в чистом javascript. Имеет ли смысл переводить все имена событий в нижний регистр? Опять же, кажется редким, чтобы два события различались только по регистру (например, наличие myEvent и myevent в одном приложении, выполняющих разные действия), но я хочу получить обратную связь по этому поводу.

discussion

Самый полезный комментарий

Одно правило, которое нужно запомнить: HTML = kebab-case, JavaScript = camelCase

Под HTML я подразумеваю атрибуты и теги. Значения атрибутов являются выражениями JavaScript, когда вы используете v-bind , поэтому применяется второе утверждение.

Все 48 Комментарий

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

+
Я часто хочу написать так, чтобы увидеть разницу между компонентами и тегами.

+1

Имеет ли смысл переводить все имена событий в нижний регистр?

Да! Это имеет смысл, потому что делает код более читаемым. Я всегда пишу имена событий строчными буквами, разделяя их дефисом, а не верблюжьим. Я думаю, что добавление предупреждения для имен событий в стиле верблюда также было бы хорошо.

Означает ли это, что Vuejs будет отходить от спецификации HTML, используя аналогичный подход, такой как Angular ?

Есть ли какие-то проблемы с производительностью?

Пара мыслей о потенциальных проблемах:

  1. Пока существует обратная совместимость, я буду хладнокровен к тому, что в конечном итоге будет решено, но, вероятно, буду продолжать использовать метод случая кебаба.
  2. Некоторых может сбить с толку отсутствие различия между верблюжьим и нижним верблюжьим регистром. Вообще говоря, var CamelCase будет ссылаться на класс, а var camelCase будет ссылаться на неклассовую переменную, var camelCase = new CamelCase(); . Но я не думаю, что это будет проблемой, потому что вы не захотите создавать классы, названные в честь ваших компонентов.
  3. Я соглашусь, что создание двух уникальных событий, различающихся только случаем, было бы очень плохим программированием.

Меня больше всего беспокоит появление странных несоответствий в том, как люди кодируют. Например, все они действительны и идентичны: :myprop="" :myProp="" :mYpRoP="" :my-prop="" .

👎 Сохраняйте kebab-case в разметке и camel case в коде. Это часть спецификации HTML, и игнорирование регистра будет более сложной кривой обучения для тех, кто пришел из других фреймворков или уже изучил стандарт.

Я согласен с @Teevio , согласованность будет потеряна

HTML использует kebab-case, и общепринятым стандартом сообщества является то, что ECMAScript является языком camelCase. Мы должны хранить их отдельно, а не _скрывать_ (в реакции единственный способ, которым вы можете реагировать на визуализацию пользовательского атрибута, — это через data-* и aria-*, что обеспечивает согласованность).

Объяснение того, почему (скажем, по ссылке MDN или даже здесь) camelCase <-> kebab-case для _beginner_, очень поможет новичку в понимании HTML.

Согласитесь с Эваном, удобочитаемость и согласованность кода важнее!
+1

Для меня это будет выглядеть очень странно иметь camelCase внутри HTML.

HTML это HTML, JS это JS

текущая версия просто супер

Я использую Vue в течение 6 месяцев, и это все еще заставляет меня каждый раз :( не имеет большого значения, поскольку предупреждение для Vue настолько хорошо, что я знаю, что я сделал, но я могу полностью понять идею здесь и поддержать ее +1

+1 Обратная совместимость тоже.

+1
Я согласился. нам нужно сохранить обратную совместимость.

Имеет ли смысл переводить все имена событий в нижний регистр?

Я согласен с @azamat-sharapov

Компоненты @Teevio Vue — это примерно классы: когда вы делаете var MyComp = Vue.extend({ .. }) , вы можете делать var myComp = new MyComp() . Что касается проблемы множественного допустимого синтаксиса, она уже существует: :my-prop , :MY-PROP и :mY-pRop все работают так же, как сейчас, потому что HTML просто отбрасывает всю информацию о регистре. Это не сильно отличается от предлагаемой функции. Как и во всех спорах о стиле, все дело в том, чтобы выбрать стиль и придерживаться его.

Re @jamesxv7 @moe-szyslak @jonagoldman и другие, у которых есть опасения по поводу отхода от стандарта HTML: абсолютно допустимо писать теги/атрибуты camelCase в HTML, просто сопоставление имен тегов/атрибутов будет выполняться без учета регистра. . Вот что говорит спецификация :

В документах в синтаксисе HTML:

Имена тегов для элементов HTML могут быть написаны любым сочетанием строчных и прописных букв, которые соответствуют именам элементов, указанным в разделе HTML-элементов этого документа, без учета регистра; то есть имена тегов нечувствительны к регистру.
Имена атрибутов для HTML-элементов могут быть написаны любым сочетанием строчных и прописных букв, которые нечувствительны к регистру и соответствуют именам атрибутов, приведенным в разделе HTML-элементы этого документа; то есть имена атрибутов нечувствительны к регистру.

Таким образом, если использование PascalCase/camelCase улучшает согласованность/читабельность кода, это полностью соответствует спецификации. Это может быть не для всех, но если вы предпочитаете чехол для кебаба, вы можете продолжать использовать его.

И, в частности, re @jamesxv7 : это отличается от того, что делает Angular 2. Angular 2 делает свои шаблоны чувствительными к регистру, вводя настраиваемый анализатор HTML. Напротив, Vue фактически следует спецификации, делая аналоги JS нечувствительными к регистру.

Я предпочитаю хранить кебаб в html. Мне нравится идея согласованности, но мне больше нравится идея соответствия спецификациям.

Найден тег camelCase:. HTML нечувствителен к регистру. Использоватьвместо. Vue автоматически сопоставит его с компонентами, определенными с помощью идентификаторов camelCase в JavaScript.

Это предупреждение уже довольно кратко описывает, как работает регистрация компонентов. Тем не менее, как уже упоминали другие, я думаю, что использование camelCase в HTML — это здорово, пока есть возможность продолжать писать кебаб.

@ yyx990803 да, согласен. Просто пытаюсь придумать как можно больше аргументов против этого, но, честно говоря, у меня нет ни одного, который бы врезался. Как вы упомянули, в конце концов, мы спорим о стилистическом выборе. Я лично считаю, что пока мы можем придерживаться того, что у нас уже есть, имея при этом возможность использовать новые вещи (но не принудительно), я согласен с упомянутыми изменениями.

Если kebab-case все еще работает и использование camelCase/PascalCase является вариантом, который не ломает BC, когда я их использую, то я не могу быть против добавления. Это не изменение, которое заставляет меня делать что-то другое. Это просто новый вариант.

Единственное, что я мог бы сказать или предложить, это убедиться, что этот вариант хорошо задокументирован и — Эван, как всегда, молодец!

Скотт

Может быть, мы сможем сделать из этого вариант: предупреждение или игнорирование.
Скажем, у меня есть компонент: myComponent
и я называю это в html как mycompOnent Лично я предпочел бы предупреждение, например:
we found something that would match "myComponent": "mycompOnent" (line 152), use "my-component" instead
То же самое для реквизита, конечно.
Я думаю, что читаемость позже важнее, чем сама вещь, работающая с первой попытки.

Я также наткнулся на проблемы с kebab-case/camelCase. Но настоящая проблема заключалась в том, что я не получил предупреждений о том, что не так;)

По умолчанию может быть, что нет предупреждения, и оно просто работает, это не имеет значения для меня.
Также предупреждения должны быть видны только в режиме отладки, я думаю

А как насчет таких вещей, как atone vs a-tone vs at-one ? Я полагаю, что они довольно редкие явления, хотя.

Реквизиты кебаба @simplesmiler по-прежнему будут сопоставляться с учетом регистра по старым правилам.

Это не способствует прозрачности веб-стандартов. В спецификации пользовательских элементов указано, что имена должны содержать дефис: <my-component/>

Как насчет того, что сказал @simplesmiler : addOne и adDone будут выполнять один и тот же код. Это было бы особенно неприятно для реализации событий,

И поскольку html нечувствителен к регистру, давайте не будем вводить идею использования регистра из библиотеки. Эта реализация будет способствовать только прописке в html, что, на мой взгляд, является плохой идеей.

Также мы используем дефисное разделение в именах файлов. Убрать их и там и начать добавлять кожух?

И наконец: сосуществование системы расшифровки и регистра продвигает разные стили кодирования для новых разработчиков в команде.

Я предпочитаю подход @paulpflug ; Надлежащие предупреждения в этой области очень помогли бы.

Я не сторонник создания случая HTML Pascal/Camel. Это нарушает веб-стандарты, я знаю, что приятно сохранять последовательность.

Пытаясь сделать вещи хоть немного последовательными, вы добавляете еще один уровень сложности. Это также может быть заманчивой плохой практикой. Библиотека должна способствовать соблюдению стандартов и не вводить разработчиков в заблуждение, поскольку однажды им, возможно, придется работать в месте, где не используется Vue, что приведет к непониманию того, почему HTML анализируется по-разному.

Я полностью согласен с @paulpflug : добавление предупреждения означает меньше работы над производственным кодом и возвращает разработчиков к написанию корректного кода.

Хороший аргумент в пользу того, почему это не следует реализовывать: http://eisenbergeffect.bluespire.com/on-angular-2-and-html/

Обычно это основная причина, по которой людям не нравится Angular 2. Я полностью согласен с тем, чтобы библиотеки соответствовали стандартам. Когда-то он был разработан для HTML с учетом регистра, но был отброшен из-за слишком большого количества проблем и создания ситуаций слишком большой гибкости.

@blake-newman: Что касается этого , я думаю, что @yyx990803 уже говорил об этом в предыдущем комментарии .

@ jamesxv7 Этот комментарий довольно хорошо подводит итог; Эван не предлагает изменить спецификацию HTML, он предлагает изменить то, как Vue находит имена компонентов. Вместо того, чтобы преобразовывать кебаб в верблюд и находить соответствующий компонент, он, вероятно, будет удалять тире (для размещения кебаба), а затем искать компоненты без учета регистра. Сам HTML по-прежнему будет соответствовать спецификации. Это также позволило бы нам использовать любой случай, который мы хотим. Мне кажется, это не злой и не плохой выбор :)

@ yyx990803 вы планируете, что стиль <MyComponent> будет продвигаемым стилем (т.е. документы и примеры будут написаны так), или это будет просто вариант, а стиль кебаб-кейса останется основным?

@blake-newman прочитайте этот комментарий - он соответствует стандарту :)

@paulpflug @guidobouman : уже есть предупреждения для тегов и атрибутов camelCase, если вы используете последние версии vue-loader или vueify . Однако проверки camelCase должны выполняться во время компиляции, поскольку во время выполнения информация о регистре уже была бы потеряна из-за поведения парсера HTML. Поэтому, если вы используете Vue без vue-loader или vueify , никаких предупреждений не будет (и не может быть).

@ yyx990803 - Но в спецификации @blake-newman, связанной с веб-компонентами, указано следующее:

Тип пользовательского элемента идентифицирует интерфейс пользовательского элемента и представляет собой последовательность символов, которая должна соответствовать произведению NCName, должна содержать символ _U+002D HYPHEN- MINUS_ и

Я просто не слишком уверен, как это относится к компонентам Vue. В документах вы говорите, что пытаетесь свободно следовать стандарту веб-компонентов.

Вы могли заметить, что компоненты Vue.js очень похожи на пользовательские элементы, которые являются частью спецификации веб-компонентов. На самом деле, синтаксис компонента Vue.js слабо смоделирован по спецификации.

Итак, я бы сказал, что сначала нужно изменить спецификацию, чтобы разрешить camelCase и PascalCase.

Скотт

@smolinari в документах Vue говорится, что это «свободно смоделировано», а не «строго», и, на мой взгляд, это оставляет место для этого изменения.

@ yyx990803 yyx990803 информация о деле может быть потеряна, но предупреждение все равно может быть.
Когда я написал «mycOmponent» в шаблоне, он будет проанализирован до mycomponent , но ожидается, что это my-component , тогда Vue (в режиме отладки) должен искать mycomponent помимо my-component и предупредите меня о неправильном использовании. Информация о потерянном деле здесь не имеет значения.
Может быть возможность подавить предупреждение и вместо этого сопоставить напрямую (соответствует вашему предложенному поведению).

-1 к переходу на camelCase/PascalCase. Было бы несколько неприятно видеть JS-подобный синтаксис в HTML. По той же причине я терпеть не могу jsx.
+1 к предложению @paulpflug . Если проблема заключается в адаптации новичков, почему бы просто не выпустить предупреждение, информирующее пользователя о проблеме?

@paulpflug звучит как верная идея!

Я согласен, наличие предупреждения с надписью 'mycomponent' is missing, did you mean 'my-component'? кажется лучше, чем тихая замена.

@yyx990803 yyx990803 Можно ли сделать это с помощью API глобальной опции?
например
Vue.config.kebab = true (по умолчанию) -> <my-component :my-prop="msg"></my-component>
Vue.config.kebab = false -> <MyComponent :myProp="msg"></MyComponent>

@yyx990803
просто интересно, к какому идеалу мы стремимся?
как сказал @rpkilby , <MyComponent myCustomProp="myProp" data-name="prop" aria-label="Close" onclick="myDialog.close()"> выглядит странно.

По сути, проблема существует потому, что js и html — разные технологии и используют разные системы именования. И использование одного и того же случая (кебаб или верблюд) в обеих технологиях приведет к перемещению странностей из одного места в другое, но основная проблема сохранится .
Поэтому я считаю, что лучшее, что мы можем сделать, это провести линию. и текущая строка, т.е. kebab case в контексте html и camleCase (и PascalCase) в контексте js очень хороши .

так что ИМО, мы должны просто поддерживать текущие соглашения, а не искать лучшее. И, конечно же, используйте предупреждение, чтобы помочь новичкам

@prog-rajkamal да, теперь я склонен просто реализовать предупреждение.

Теперь я голосую :+1: просто за добавление предупреждения.

Скотт

:+1: за добавление предупреждения

:+1: тоже за предупреждение

Закрыто через ccf9bede6bc39fb62e43e1efe98136c5f35dae6b и d7b55c4ee8491dbd853e28a1527050d2d1e7deab

Предупреждение было бы здорово. Я только что потратил час, пытаясь понять, почему на мое пользовательское событие не ответили (ответ заключался в том, что у него было имя в верблюжьем корпусе).

Есть предупреждение, когда у вас есть соответствующий компонент или реквизит, который будет реагировать на версию kebab-case вашего компонента или реквизита PascalCase . Если вы сделаете опечатку в событии, Vue мало что может с этим поделать.

Или вы имеете в виду существующие реквизиты событий по умолчанию, такие как v-on:keyup или @keyup , короче?

@guidobouman в моем файле шаблона у меня было <my-component v-on:customEvent="myMethod"> . В дочернем компоненте у меня было this.$emit('customEvent'); . Фактическое событие, прослушиваемое родителем, customevent , а не customEvent , конечно, но мне понадобилась целая вечность, чтобы понять это, потому что его нелегко отлаживать. Я подумал, что было бы хорошо предупредить, что атрибут верблюжьего регистра не будет анализироваться как таковой для таких забывчивых людей, как я. Возможно, это уже обсуждалось выше, и если да, то прошу прощения.

@anthonygore , к сожалению, это невозможно, потому что браузер преобразует html в нижний регистр до того, как Vue получит к нему доступ.

Мой вопрос: почему Vue не может преобразовать его для нас? Почему мы должны помнить о шашлычном деле в

Одно правило, которое нужно запомнить: HTML = kebab-case, JavaScript = camelCase

Под HTML я подразумеваю атрибуты и теги. Значения атрибутов являются выражениями JavaScript, когда вы используете v-bind , поэтому применяется второе утверждение.

Мой вопрос: почему Vue не может преобразовать его для нас? Почему мы должны помнить о kebab-case в файлах vue? Это делает вещи более неудобными для новичков... Я просто потратил последние 20 минут на это...

потратил впустую последние 1,5 часа, потому что я не просто погуглил... dxmn

Была ли эта страница полезной?
0 / 5 - 0 рейтинги