Встроенные директивы¶
Директивы — это функции, которые могут расширить Lit, настраивая способ рендеринга выражения. В Lit есть несколько встроенных директив, которые помогают решать различные задачи рендеринга:
Стилизация:
Декоратор | Описание |
---|---|
classMap | Присваивает список классов элементу на основе объекта. |
styleMap | Устанавливает список свойств стиля для элемента, основанного на объекте. |
Циклы и условия:
Декоратор | Описание |
---|---|
when | Выдает один из двух шаблонов на основе условия. |
choose | Отображает один из многих шаблонов на основе ключевого значения. |
map | Преобразовывает итерируемый объект с помощью функции. |
repeat | Выводит значения из итерируемой таблицы в DOM с дополнительным ключом, чтобы обеспечить диффузию данных и стабильность DOM. |
join | Объединяет значения из итерабельной таблицы с помощью объединяющего значения. |
range | Создает итерабельную таблицу чисел в последовательности, полезной для итерации определенное количество раз. |
ifDefined | Устанавливает атрибут, если его значение определено, и удаляет атрибут, если не определено. |
Кэширование и обнаружение изменений:
Декоратор | Описание |
---|---|
cache | Кэширует отрисованный DOM при изменении шаблонов, а не удаляет его. |
keyed | Связывает отрисовываемое значение с уникальным ключом, заставляя DOM перерисовываться при изменении ключа. |
guard | Переоценивает шаблон только при изменении одной из его зависимостей. |
live | Устанавливает атрибут или свойство, если оно отличается от живого значения DOM, а не от последнего отрендеренного значения. |
Ссылка на рендеринг DOM:
Декоратор | Описание |
---|---|
ref | Получает ссылку на элемент, отрендеренный в шаблоне. |
Рендеринг специальных значений:
Декоратор | Описание |
---|---|
templateContent | Рендерит содержимое элемента <template> . |
unsafeHTML | Возвращает строку в виде HTML, а не текста. |
unsafeSVG | Выводит строку не как текст, а как SVG. |
Асинхронный рендеринг:
Декоратор | Описание |
---|---|
until | Отрисовывает содержимое, пока не будет выполнено одно или несколько обещаний. |
asyncAppend | Добавляет значения из AsyncIterable в DOM по мере их получения. |
asyncReplace | Возвращает последнее значение из AsyncIterable в DOM по мере его получения. |
Объединяйте только то, что используете
Эти директивы называются "встроенными", потому что они входят в пакет Lit. Но каждая директива — это отдельный модуль, поэтому ваше приложение включает только те директивы, которые вы импортируете.
Вы также можете создавать свои собственные директивы. Для получения дополнительной информации смотрите Пользовательские директивы.
Стилизация¶
classMap
¶
Устанавливает список классов для элемента на основе объекта.
Импорт
1 |
|
Синтаксис
1 |
|
- Место использования:
-
Выражение атрибута
class
(должно быть единственным выражением в атрибутеclass
)
Директива classMap
использует API element.classList
для эффективного добавления и удаления классов в элемент на основе объекта, переданного пользователем. Каждый ключ в объекте рассматривается как имя класса, и если значение, связанное с ключом, истинно, то этот класс добавляется в элемент. При последующих рендерах все ранее установленные классы, которые являются ложными или больше не содержатся в объекте, удаляются.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Карта classMap
должна быть единственным выражением в атрибуте class
, но она может быть объединена со статическими значениями:
1 2 3 |
|
Изучите classMap
больше в playground.
styleMap
¶
Устанавливает список свойств стиля для элемента на основе объекта.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Выражение атрибута
style
(должно быть единственным выражением в атрибутеstyle
)
Директива styleMap
использует API element.style
для эффективного добавления и удаления встроенных стилей в элемент на основе объекта, переданного пользователем. Каждый ключ в объекте рассматривается как имя свойства стиля, а значение — как значение этого свойства. При последующих рендерах все ранее установленные свойства стиля, которые не определены или null
, удаляются (устанавливаются в null
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Для CSS-свойств, содержащих тире, вы можете использовать эквивалент верблюжьего регистра или заключить имя свойства в кавычки. Например, CSS-свойство font-family
можно записать как fontFamily
или 'font-family'
:
1 2 |
|
Ссылайтесь на пользовательские свойства CSS, такие как --custom-color
, заключая все имя свойства в кавычки:
1 |
|
Карта styleMap
должна быть единственным выражением в атрибуте style
, но она может быть объединена со статическими значениями:
1 2 3 |
|
Изучите styleMap
подробнее в playground.
Циклы и условия¶
when
¶
Выводит один из двух шаблонов на основе условия.
Импорт:
1 |
|
Синтаксис:
1 2 3 4 5 |
|
- Место использования:
-
Любое
Если condition
истинно, возвращает результат вызова trueCase()
, иначе возвращает результат вызова falseCase()
, если определено falseCase
.
Это удобная обертка вокруг тернарного выражения, которая позволяет написать встроенное условие без else
.
1 2 3 4 5 6 7 8 9 10 11 |
|
choose
¶
Выбирает и оценивает шаблонную функцию из списка case, основываясь на соответствии заданного value
.
Импорт
1 |
|
Синтаксис:
1 2 3 4 5 |
|
- Место использования:
-
Любое
Случаи структурируются как [caseValue, func]
. value
сопоставляется с caseValue
по принципу строгого равенства. Выбирается первое совпадение. Значения case
могут быть любого типа, включая примитивы, объекты и символы.
Это похоже на оператор switch
, но в виде выражения и без отбрасывания.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
map
¶
Возвращает итерабельную таблицу, содержащую результат вызова f(value)
для каждого значения в items
.
Импорт
1 |
|
Синтаксис:
1 2 3 4 |
|
- Место использования:
-
Любое
map()
— это простая обертка вокруг цикла for/of loop, которая делает работу с итерациями в выражениях немного проще. map()
всегда обновляет любой DOM, созданный на месте — он не делает никаких диффирингов или перемещений DOM. Если вам это нужно, смотрите repeat. map()
меньше и быстрее, чем repeat()
, поэтому, если вам не нужны диффиринги и стабильность DOM, предпочтите map()
.
1 2 3 4 5 6 7 8 9 |
|
repeat
¶
Выводит значения из итерируемого файла в DOM с дополнительным ключом, чтобы обеспечить диффузию данных и стабильность DOM.
Импорт
1 |
|
Синтаксис:
1 2 3 4 |
|
- Место использования:
-
Дочернее выражение
Повторяет серию значений (обычно TemplateResults
), сгенерированных из итерируемой таблицы, и эффективно обновляет эти элементы при изменении итерируемой таблицы. При использовании keyFn
связь между ключами и DOM поддерживается между обновлениями путем перемещения сгенерированного DOM, когда это необходимо, и это, как правило, самый эффективный способ использования repeat
, поскольку он выполняет минимум ненужной работы при вставках и удалениях.
Если вы не используете функцию ключа, вам следует рассмотреть возможность использования map()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Если keyFn
не указан, repeat
будет работать аналогично простому отображению элементов в значения, и DOM будет повторно использоваться для потенциально разных элементов.
Обсуждение того, когда следует использовать повтор
, а когда — стандартный контроль потока JavaScript, см. в Когда использовать map или repeat.
Подробнее о `repeat можно узнать в playground.
join
¶
Возвращает итерабельную таблицу, содержащую значения в items
, чередующиеся со значением joiner
.
Импорт
1 |
|
Синтаксис:
1 2 3 4 5 6 7 8 9 |
|
- Место использования:
-
Любое
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
range
¶
Возвращает итерабельную таблицу целых чисел от start
до end
(эксклюзивных) с инкрементом на step
.
Импорт
1 |
|
Синтаксис:
1 2 3 4 5 6 7 |
|
- Место использования:
-
Любое
1 2 3 4 5 6 7 |
|
ifDefined
¶
Устанавливает атрибут, если его значение определено, и удаляет атрибут, если не определено.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Выражение атрибута
Для частей AttributeParts устанавливает атрибут, если значение определено, и удаляет атрибут, если значение не определено (undefined
или null
). Для других типов частей эта директива не используется.
Когда в одном значении атрибута содержится более одного выражения, атрибут будет удален, если любое выражение использует ifDefined
и оценивается как undefined
/null
. Это особенно полезно для установки атрибутов URL, когда атрибут не должен устанавливаться, если необходимые части URL не определены, чтобы предотвратить 404.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Изучите ifDefined
подробнее в playground.
Кэширование и обнаружение изменений¶
cache
¶
Кэширует отрисованный DOM при смене шаблонов вместо того, чтобы отбрасывать его. Вы можете использовать эту директиву для оптимизации производительности рендеринга при частом переключении между большими шаблонами.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Выражение
Child
Когда значение, переданное в cache
, меняется между одним или несколькими TemplateResult
, отрисованные DOM-узлы для данного шаблона кэшируются, когда они не используются. Когда шаблон меняется, директива кэширует текущие узлы DOM перед переключением на новое значение и восстанавливает их из кэша при переключении обратно на ранее отрендеренное значение, вместо того чтобы создавать узлы DOM заново.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Когда Lit перерисовывает шаблон, он обновляет только измененные части: он не создает и не удаляет больше DOM, чем нужно. Но когда вы переключаетесь с одного шаблона на другой, Lit удаляет старый DOM и создает новое дерево DOM.
Директива cache
кэширует сгенерированный DOM для данного выражения и шаблона ввода. В приведенном выше примере она кэширует DOM для шаблонов summaryView
и detailView
. Когда вы переключаетесь с одного представления на другое, Lit подменяет кэшированную версию нового представления и обновляет ее последними данными. Это может повысить производительность рендеринга при частом переключении между этими представлениями.
Подробнее о cache
можно узнать в playground.
keyed
¶
Связывает отрисовываемое значение с уникальным ключом. При изменении ключа предыдущий DOM удаляется и утилизируется перед рендерингом следующего значения, даже если значение — например, шаблон — остается прежним.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Любое выражение
keyed
полезен, когда вы отрисовываете элементы с состоянием и вам нужно убедиться, что все состояние элемента будет очищено при изменении некоторых критических данных. По сути, это отказ от стандартной стратегии повторного использования DOM в Lit.
keyed
также полезен в некоторых сценариях анимации, если вам нужно принудительно создать новый элемент для анимации "входа" или "выхода".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
guard¶
Переоценивает шаблон только при изменении одной из его зависимостей, чтобы оптимизировать производительность рендеринга за счет предотвращения ненужной работы.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Любое выражение
Выдает значение, возвращаемое valueFn
, и переоценивает valueFn
только тогда, когда одна из зависимостей меняет идентификатор.
Где:
dependencies
— массив значений, которые необходимо отслеживать на предмет изменений.valueFn
— функция, возвращающая рендерируемое значение.
guard
полезен при работе с неизменяемыми шаблонами данных, предотвращая дорогостоящую работу до обновления данных.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
В этом случае дорогостоящая функция calculateSHA
запускается только при изменении свойства value
.
Изучите guard
подробнее на playground.
live¶
Устанавливает атрибут или свойство, если оно отличается от живого значения DOM, а не от последнего рендерированного значения.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Атрибут или выражение свойства
При определении того, обновлять ли значение, проверяет значение выражения по живому значению DOM, а не по поведению Lit по умолчанию — по последнему установленному значению.
Это полезно для случаев, когда значение DOM может измениться за пределами Lit. Например, при использовании выражения для установки свойства <input>
элемента value
, текста редактируемого элемента содержимого или для пользовательского элемента, изменяющего свои свойства или атрибуты.
В этих случаях, если значение DOM изменится, а значение, установленное с помощью выражения Lit, нет, Lit не будет знать, что нужно обновить значение DOM, и оставит его в покое. Если вы не хотите этого — если вы хотите перезаписать значение DOM связанным значением независимо ни от чего — используйте директиву live()
.
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
live()
выполняет строгую проверку равенства с живым значением DOM, и если новое значение равно живому значению, ничего не делает. Это означает, что live()
не следует использовать, если выражение приводит к преобразованию типов. Если вы используете live()
с выражением атрибута, убедитесь, что в выражении передаются только строки, иначе выражение будет обновляться при каждом рендере.
Изучите live
подробнее на playground.
Рендеринг специальных значений¶
templateContent
¶
Рендерит содержимое элемента <template>
.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Детское выражение
Шаблоны Lit закодированы на Javascript, поэтому в них можно встраивать выражения Javascript, которые делают их динамичными. Если у вас есть статичный HTML <template>
, который нужно включить в шаблон Lit, вы можете использовать директиву templateContent
, чтобы клонировать содержимое шаблона и включить его в свой шаблон Lit. Если ссылка на элемент шаблона не изменяется между рендерами, последующие рендеры будут безотказными.
Обратите внимание, что содержимое шаблона должно контролироваться разработчиком и не должно быть создано с использованием недоверенной строки. Примерами недоверенного содержимого являются параметры строки запроса и значения пользовательского ввода. Недоверенные шаблоны, созданные с помощью этой директивы, могут привести к уязвимостям межсайтового скриптинга (XSS).
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
Изучите templateContent
больше в playground.
unsafeHTML
¶
Возвращает строку в виде HTML, а не текста.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Дочернее выражение
Ключевая особенность синтаксиса шаблонов Lit заключается в том, что только строки из литералов шаблонов анализируются как HTML. Поскольку литералы шаблонов могут быть созданы только в доверенных файлах сценариев, это служит естественной защитой от XSS-атак, внедряющих недоверенный HTML. Однако могут быть случаи, когда в шаблоне Lit необходимо отобразить HTML, созданный не в файлах сценариев, например, доверенный HTML-контент, полученный из базы данных. Директива unsafeHTML
разберет такую строку как HTML и отобразит ее в шаблоне Lit.
Обратите внимание, что строка, передаваемая в unsafeHTML
, должна контролироваться разработчиком и не содержать недоверенного содержимого. Примерами недоверенного содержимого могут быть параметры строки запроса и значения из пользовательского ввода. Недоверенное содержимое, отображаемое с помощью этой директивы, может привести к уязвимости межсайтовый скриптинг (XSS).
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
Изучите unsafeHTML
подробнее на игровой площадке.
unsafeSVG
¶
Выводит строку в виде SVG, а не текста.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Дочернее выражение
Как и в случае с unsafeHTML
, возможны случаи, когда в шаблоне Lit необходимо отобразить SVG-контент, не содержащийся в файлах сценариев, например, доверенный SVG-контент, полученный из базы данных. Директива unsafeSVG
разберет такую строку как SVG и отобразит ее в шаблоне Lit.
Обратите внимание, что строка, передаваемая в unsafeSVG
, должна контролироваться разработчиком и не содержать недоверенного содержимого. Примерами недоверенного содержимого могут быть параметры строки запроса и значения из пользовательского ввода. Недоверенное содержимое, отображаемое с помощью этой директивы, может привести к уязвимостям межсайтового скриптинга (XSS).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Изучите unsafeSVG
подробнее в playground.
Ссылки на визуализированный DOM¶
ref
¶
Получает ссылку на элемент, отображаемый в DOM.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Выражение элемента
Хотя большинство манипуляций с DOM в Lit можно выполнять декларативно, используя шаблоны, в сложных ситуациях может потребоваться получить ссылку на элемент, отображенный в шаблоне, и манипулировать им императивно. В качестве примера можно привести фокусировку элемента управления формой или вызов библиотеки императивных манипуляций с DOM на элементе контейнера.
При размещении на элементе в шаблоне директива ref
будет извлекать ссылку на этот элемент после рендеринга. Ссылка на элемент может быть получена одним из двух способов: либо путем передачи объекта Ref
, либо путем передачи обратного вызова.
Объект Ref
выступает в качестве контейнера для ссылки на элемент и может быть создан с помощью вспомогательного метода createRef
, находящегося в модуле ref
. После рендеринга свойство Ref
value
будет установлено на элемент, где к нему можно будет получить доступ в пост-рендерном жизненном цикле, например updated
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Директиве ref
также можно передать обратный вызов ref. Обратный вызов будет вызываться каждый раз при изменении элемента, на который ссылается ссылка. Если обратный вызов ref рендерится на другую позицию элемента или удаляется при последующем рендеринге, то сначала он будет вызван с undefined
, а затем еще один вызов с новым элементом, на который он был рендерирован (если таковой имеется). Обратите внимание, что в LitElement
обратный вызов будет вызван автоматически, привязанный к главному элементу.
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
Изучите ref
больше в playground.
Асинхронный рендеринг¶
until
¶
Отрисовывает содержимое, пока не разрешится одно или несколько обещаний.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Любое выражение
Принимает ряд значений, включая Promise
. Значения отображаются в порядке приоритета: первый аргумент имеет наивысший приоритет, а последний — наименьший. Если значение является обещанием, то до его разрешения будет отображаться значение с более низким приоритетом.
Приоритет значений может быть использован для создания содержимого-заместителя для асинхронных данных. Например, первым (с наивысшим приоритетом) аргументом может быть Promise
с ожидающим содержимым, а в качестве второго (с более низким приоритетом) аргумента может использоваться шаблон индикатора загрузки, не относящийся к Promise
. Индикатор загрузки отобразится сразу, а основной контент — после разрешения Promise
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Изучите until
больше на игровой площадке.
asyncAppend
¶
Добавляет значения из AsyncIterable
в DOM по мере их получения.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Дочернее выражение
asyncAppend
выводит значения генератора async iterable, добавляя каждое новое значение после предыдущего. Обратите внимание, что генераторы async также реализуют протокол async iterable, и поэтому могут быть использованы asyncAppend
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Изучите asyncAppend
подробнее на игровой площадке.
asyncReplace
¶
Возвращает последнее значение из AsyncIterable
в DOM по мере его получения.
Импорт
1 |
|
Синтаксис:
1 |
|
- Место использования:
-
Дочернее выражение
Подобно asyncAppend
, asyncReplace
отображает значения async iterable, заменяя предыдущее значение на каждое новое.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Изучите asyncReplace
подробнее в playground.