Что такое Vue, что позволяет разработчикам использовать свойство класса для элементов DOM? - PullRequest
0 голосов
/ 11 марта 2020
Фреймворки

JavaScript, такие как React и Svelte , не позволяют разработчикам использовать свойство class для элемента DOM, поскольку ключевое слово class зарезервировано в JavaScript. Между тем, другие фреймворки, такие как Vue, каким-то образом обойдут это.

Что такого в реализации Vue, которая позволяет Vue разработчикам использовать ключевое слово class для элементов? Я предполагаю, что это что-то с тем, как Vue конвертирует .vue файлов в HTML, CSS и JavaScript, но мне любопытно узнать о деталях.

Редактировать: Svelte не использует виртуальный DOM , а вы можете использовать класс prop с Svelte.

Ответы [ 4 ]

4 голосов
/ 11 марта 2020

tldr; JSX (язык React) является расширенным набором JavaScript (где class является зарезервированным ключевым словом), в то время как Vue и Svelte имеют языки шаблонов, которые являются расширенными наборами HTML, что позволяет использовать class, как в HTML.


Говоря здесь для Svelte.

Сначала давайте исправим ложную предпосылку:

* Платформы 1011 *

JavaScript, такие как React и Svelte , не позволяют разработчикам использовать свойство class в виртуальном элементе DOM, поскольку ключевое слово class зарезервировано в JavaScript.

* 1016. *

Svelte разрешает использование ключевого слова class как для элементов, так и для компонентов. Вам просто нужно работать в рамках применимых ограничений. Мы возвращаемся к этому.

Давайте начнем с React. Ну, на самом деле JSX. JSX является строгим надмножеством JS. Давайте обратимся к этому хорошему объяснению . JSX является надмножеством JS и синтаксически (любая JS программа является допустимой JSX) и семантически (любая JS программа ведет себя одинаково при интерпретации как JSX).

In Для этого JSX должен учитывать все ограничения JS, из которых «класс является зарезервированным ключевым словом». Вот почему React не допускает ключевое слово class.

Обратите внимание, что это не технические ограничения . Реагирование может переосмыслить ключевое слово class и заставить его работать в JSX. Но это сделало бы JSX не строго надмножеством JS. Почему? Потому что тогда, в некоторых случаях, один и тот же код JS не будет вести себя одинаково при интерпретации как чистый JS или как JSX (а именно, наличие переменной с именем class должно cra sh для быть JS).

Это философское ограничение. В какой-то момент разработчики JSX должны были оценить неудобство, связанное с невозможностью использования ключевого слова class, из-за того, что оно не является строгим надмножеством JS. С одной стороны, вы получаете одну маленькую хитрость, с другой - вы резко понижаете рейтинг от математически чистого суперсета до просто «еще одного случайного языка шаблонов».

Легко почувствовать сильный математический уклон, исходящий от Реагировать с акцентом на чистые функции, «представление как функция состояния», однонаправленные потоки данных и т. Д. c. На самом деле это очень важный вывод из React. Они внесли много преимуществ из математики в повседневную разработку приложений. И поэтому, вполне понятно (для меня), эта группа разработчиков одобрила (поддерживает) чистоту по сравнению с незначительными удобствами.

Быть надмножеством JS дает много преимуществ. Даже если вы ничего не знаете о JSX, вы можете написать его немедленно, используя имеющиеся у вас знания JS. Пока вы не начнете использовать дополнительные функции JSX, вы можете предсказать все поведения вашего кода, потому что все будет вести себя одинаково.

Теперь, в соответствии со спецификой Svelte ... Svelte делает не используйте JSX (и ни Vue в большинстве случаев, насколько я знаю). Они используют свой собственный язык шаблонов. Не уверен для Vue, но для Svelte это суперсет, не JS, а HTML. Рич Харрис, создатель Svelte, однажды назвал этот HTMLX в своем выступлении (не уверен, насколько официальной является эта терминология в настоящее время). Лично это одна из главных причин, почему мне так комфортно с Svelte. Я нахожу трудным написать HTML is JS, в то время как запись HTML (X) с естественным видом, в конце концов, производит HTML, кажется просто ... естественной! Но я отвлекся ...

Итак, дело в том, что Svelte тоже должен играть в пределах своей собственной выбранной l aws. Есть 2 из них, которые имеют отношение к данному вопросу. И то, и другое имеет смысл, и оба могут быть обойдены.

Но сначала, чтобы устранить любое заблуждение, Svelte разрешает использовать ключевое слово class для нативных элементов (в отличие от компонентов Svelte):

<div class="whatever">No problem with that</div>

Это не было бы надлежащим надмножеством HTML, если бы этого не произошло.

В этом контексте class на самом деле является «директивой», что означает, что он добавил силу, по сравнению с чистым HTML классом. Например:

<script>
  let blue = true
</script>

<!-- will render as: <div class="blue"></div> -->
<div class:blue />

<!-- will render as: <div class="red"></div> -->
<div class:red={blue} />

<!-- you can have several of them too... -->
<div class="foo" class:red class:blue />

Так что Svelte позволяет использовать ключевое слово class, в этом нет никаких сомнений. Для нативных элементов это.

Теперь для компонентов история немного другая. А вот и 2 l aws, о которых я упоминал ранее.

Первый - это то, что компоненты Svelte не требуют наличия одного root элемента. Или вообще каких-либо элементов.

<script>
  console.log('I am a valid Svelte component with no elements')
</script>
<!-- no code omitted -->
<p>I am a valid Svelte component</p>
<p>Too.</p>

Следствием этого является то, что Svelte не может точно знать, к какому элементу (элементам) он должен автоматически применить набор class на охватывающий компонент. И вот, в этой ситуации это ничего не делает. Он возвращает вам элементы управления.

Это не значит, что вы не можете реализовать его, если хотите. Вы просто должны соблюдать наш второй закон: код внутри тега <script> компонента Svelte должен быть действительным JS. Здесь опять же, это не техническое ограничение, а философское. Это многократно повторялось создателем и основными разработчиками Svelte. На уровне синтаксиса, мы даже больше не говорим о надмножестве, но о равенстве. Любой Svelte JS действителен JS (обратите внимание, что члены отношения поменялись местами по сравнению с "any JS is valid JSX").

С другой стороны, Svelte JS не является семантией c надмножеством JS. Некоторые JS программы не будут вести себя одинаково при интерпретации как чистый JS, так и при интерпретации с Svelte, потому что Svelte перегружает некоторые конструкции (например, $: или export let prop) с другим значением.

Это ограничение Это влияет на нас, потому что class не является допустимым именем переменной JS, а свойства компонентов Svelte определены как JS переменных. Однако вы можете обойти это:

<script>
  // can't do, not valid JS:
  //    export let class

  // but:
  let cls = ''
  export { cls as class } // valid JS
</script>

<div class={class} />

Этот компонент затем будет использоваться следующим образом ( живой пример ):

<script>
  import MyComponent from './MyComponent.svelte'
</script>

<MyComponent class="blue" />

Так что вы также можете использовать class ключевое слово для компонентов в Svelte.

Фу. Надеюсь, вам понравится развернутый ответ!

Подводя итог, можно сказать, что если некоторые из основных структур позволяют использовать ключевое слово class, а некоторые нет, то это по философским причинам. Для JSX, как надмножества JS, имеет смысл соблюдать это ограничение. Для HTMLX Svelte бессмысленно реализовывать это ограничение без всякой причины (и перестать быть надмножеством HTML в процессе). Кроме того, в React больше внимания уделяется чистоте математики, а в Svelte больше внимания уделяется выразительности и удобству кода. Как всегда с хорошим программным обеспечением, это все в обмен!

0 голосов
/ 11 марта 2020

Библиотека React использует JSX для визуализации любых элементов DOM. JSX является своего рода расширением для JS для рендеринга HTML из javascript. JSX передается перед рендерингом в браузер. Следовательно, className должно использоваться вместо класса. Но есть несколько улучшений, переходящих с одной версии reactjs на другую.

Похоже, что аналогичный вопрос уже задавался. Найдите более подробное объяснение class vs className в React 16

0 голосов
/ 11 марта 2020

Согласно моим ответам на исследования: благодаря встроенной функции.

На стороне Vue. js https://github.com/vuejs/vue/blob/dev/dist/vue.js я обнаружил, что Vue связывает класс из объекта JavaScript с узлом. Элемент узла (vue) используется с JavaScript для присвоения вязу DOM всех классов.

Код JavaScript el.setAttribute('class', cls) подтверждает это.

  function transformNode (el, options)

и из этого вы найдете функцию в строке 5503:

  function genClassForVnode (vnode)

, которая использует

  function renderClass (staticClass, dynamicClass)

Эта функция затем используется

function updateClass (oldVnode, vnode) {
    var el = vnode.elm;
    var data = vnode.data;
    var oldData = oldVnode.data;
  [...]  
    var cls = genClassForVnode(vnode);

    // handle transition classes
    var transitionClass = el._transitionClasses;
    if (isDef(transitionClass)) {
      cls = concat(cls, stringifyClass(transitionClass));
    }

    // set the class
    if (cls !== el._prevClass) {
      el.setAttribute('class', cls);
      el._prevClass = cls;
    }
  }

note: интересны следующие функции: function addClass(el, cls) строка 7873 function bindObjectListeners(data, value) строка 2866

Помогает ли это?

0 голосов
/ 11 марта 2020

Вы не можете использовать class с React, потому что React использует React DOM, который использует имена свойств camelCase, а не классические атрибуты HTML. Вот почему в JSX (React языке рендеринга) вы должны использовать className, а не class.

Vue использует классический шаблон HTML, поэтому class допускается.

С Svelte вы сможете использовать ключевое слово class в своем шаблоне.

...