В статьях Замена JSX шаблонными литералами и Легкое создание HTML-шаблонов с помощью TLX мы представили TLX, интерфейсную библиотеку, которая объединяет ключевые функции React и Vue в одну небольшую библиотеку. В этой статье мы расскажем о директивах атрибутов, поддерживаемых TLX, а также о том, как добавить собственные директивы всего в одну строчку кода!
TLX поддерживает следующие встроенные директивы:
state
который, как вы уже догадались, устанавливает состояние данных элементов.t-for=<vname> of <array>
, который работает как его аналог JavaScript.t-for=<vname> in <object>
, который работает как его аналог JavaScript.t-foreach=<object>
, который работает как его аналог массива JavaScript, а также обрабатывает объекты.t-if=<expression>,
, который будет отображать вложенный HTML только в том случае, если<expression>
является правдой.t-on={<eventName>:<function>[,...]}>
, который прикрепляет обработчики событий к элементам.
Все встроенные директивы реализуются точно так же, как и пользовательские директивы, подробнее об этом позже.
Состояние
Атрибут state="${{name:'Joe',age:27}}",
сделает переменные name
и age
доступными для шаблонов, используемых в любом HTML, вложенном внутри элемента, объявляющего атрибут, например
<div state="${{name:'Joe',age:27}}"> Name: ${name}<br> Age: ${age} </div>
будет отображаться как:
Имя: Джо
Возраст: 27
Независимо от порядка атрибутов, атрибут state
обрабатывается перед любыми другими директивами.
Кроме того, и это относится ко всем директивам, переменная может быть скрыта дополнительным вложенным HTML, например
<div state="${{name:'Joe',age:27}}"> Name: ${name}<br> Age: ${age} <div state="${{name:'Mary'}}"> Name: ${name} </div> </div>
будет отображаться как:
Имя: Джо
Возраст: 27
Имя: Мэри
Итерации
Итерации работают немного иначе, чем Vue. Выражение итерации помещается в содержащий элемент. Этот параллельный регулярный код не только немного более точен, но и упрощает внутреннюю структуру TLX.
<ul t-for="item of ${[1,2,3]}"> <li>${item}</li> </ul>
будет отображаться как:
- 1
- 2
- 3
Для удобства также доступны переменные value
, index
и array
, как если бы был вызван [1,2,3].forEach((value,index,array)=>...)
.
Аналогичным образом HTML
<div t-for="property in ${{name:'Joe',age:27}}"> <div>${property}: ${object[property]}</div> </div>
отобразит:
имя: Джо
возраст: 27
И для удобства доступны переменные key
и object
. Следовательно, следующий результат даст тот же результат:
<div t-for="property in ${{name:'Joe',age:27}}"> <div>${property}: ${object[key]}</div> </div>
Vue не имеет директивы foreach
, которая может принимать массив или объект, TLX:
<div t-foreach="${{name:'Joe',age:27}}"> <div>${key}: ${value}</div> </div>
и
<div t-foreach="${[1,2,3]}"> <div>${key}: ${value}</div> </div>
можно использовать оба.
Условные
Условное выражение t-if
предотвратит рендеринг любого вложенного HTML, если значение его выражения является ложным; следовательно,
<div t-if="${age>27}" state="${{name:'Joe',age:27}}"> <div t-for="property in ${state}"> <div>${property}: ${object[property]}</div> </div>
ничего не будет отображать, поскольку атрибут state
обрабатывается первым и age
не превышает 27. Также обратите внимание, что сам state
доступен как переменная в пределах области элемента.
Обработчики событий
Директива t-on
поддерживает добавление нескольких обработчиков событий с одним значением, объектом, ключи которого являются именами событий, а значения - функциями, например:
<input type="text" t-on="${{focus: (event) => console.log(event),click: (event) => console.log(event)}}">
будет регистрировать все события фокуса и щелчка на консоли.
Пользовательские директивы
Всего в этих 6 директивах много силы, но что, если вам нужно больше? Вы можете создать их всего одной линией!
Директива атрибута t-if
в файле tls-directives.js
реализована настолько просто, насколько это возможно:
"t-if": (value,vnode) => { if(!value) { vnode.children = null; } }
Вот немного более сложный пример, добавленный в код пользователя, а не в tlx-directives.js
:
tlx.directives.VNode["t-capitalize"] = (_,vnode) => vnode.children.forEach((child,i) => child instanceof tlx.VNode || (vnode.children[i] = new tlx.VText({text:child.text.toUpperCase(),parent:child.parent}))))
Этот код принимает VNode и использует заглавные буквы всех дочерних элементов, которые являются строками, то есть узлами VText, до их рендеринга, независимо от значения, связанного с атрибутом, т.е. он работает как унарные атрибуты hidden
и selected
.
Пользовательские директивы назначаются tlx.directives.VNode
, и все они принимают значение директивы и виртуальное представление узла DOM, с которым связана директива, в качестве аргументов.
VNode имеет следующие свойства:
nodeName
, что похоже наtagName
, но в нижнем регистре.attributes
, который является объектом, ключи которого представляют собой имена атрибутов со значениями, которые могут быть aboolean
,number
,string
илиobject.
.children
, который представляет собой массив дочерних узлов VNode или VText.
Сданный vnode
может быть изменен любым желаемым образом.
В следующей статье мы рассмотрим настраиваемые теги и компоненты и представим мощный универсальный редактор, который инкапсулирует input
, select-one, select-multiple
иtextarea
, добавляя возможности radiogroup
и звездочки rating
.