1. Оптимизация производительности лонг-листа
в версии 2.хVue
пройдешьObject.defineProperty
Перехват данных для двусторонней привязки данных.
Однако в некоторых конкретных бизнес-сценариях компоненты должны отображать только чистые данные без каких-либо изменений.Vue
Перехват входящих данных.
Когда нужно представить большой объем данных, если это запрещеноVue
Перехват данных значительно сократит время инициализации компонентов.
::: наконечник
пройти черезObject.freeze
способ заморозить объект,Когда объект заморожен, его нельзя изменить.
:::
export default {
data: () => ({
userList: []
}),
async created() {
const userList = await this.$service.get("/getuserList");
this.userList = Object.freeze(userList);
}
};
2. Анализ производительности рендеринга компонентов Vue
На основании приведенного выше случая (长列表性能优化
), способный пройтиObject.freeze
Чтобы добиться чистой оптимизации производительности списка презентаций, как это подтвердить?
Мы можем обнаружить это через Chrome Devtools, но для того, чтобы получить точные данные анализа производительности, нам нужно включить режим производительности приложения Vue.
Включить режим производительности Vue (для режима разработки)
В машиностроенииmain.js
(перед инициализацией корневого экземпляра Vue) добавьте следующий код:
Vue.config.performance = true;
Конечно, вы также можете оценить текущую среду, если это необходимо, чтобы решить, включать ли режим производительности.
const isDev = process.env.NODE_ENV !== "production";
Vue.config.performance = isDev;
Это активирует API синхронизации, который Vue использует внутри для оценки производительности компонента, как показано ниже:
Предположим, на данный момент мы создали демонстрационный проект и имеемHello.vue
Компонент, используемый для проверки производительности рендеринга длинных списков. После запуска локального проекта откройте браузер по указанному маршруту (убедитесь, что есть загрузкаHello.vue
компонент). Откройте консоль и нажмите кнопку «перезагрузить», как показано ниже:
На этом этапе производительность страницы будет записана.Поскольку параметр Vue.config.performance был добавлен в main.js, вы сможете увидеть временной раздел в анализе на этом этапе.Как показано на изображении ниже.
На этом этапе вы обнаружите, что здесь есть 3 индикатора:
- init, время, которое потребовалось для создания экземпляра компонента
- рендеринг, время, потраченное на создание структуры vDOM
- патч, время, необходимое для преобразования структуры vDOM в фактические элементы DOM.
Проверить производительность
В этом примереhttp://localhost:8080/#/helloВ маршрутизации есть только два компонента:
App.vue
Hello.vue
App.vue
является компонентом представления, существует только один<router-view/>
Hello.vue
Просто отобразите простой длинный список (100000 условных данных), код выглядит следующим образом:
<template>
<div>
<span v-for="(item, idx) in users" :key="idx">
{{item.name}}
</span>
</div>
</template>
<script>
export default {
data () {
return {
users: []
}
},
components: {
},
created () {
let users = Array.from({ length: 100000 }, (item, index) => ({ name: index }))
this.users = users
}
}
</script>
В настоящее время,Hello.vue
компонентыrender
&patch
Время:
- render -> 924ms
- patch -> 1440ms
ИсправлятьHello.vue
изcreated
Код функции ловушки выглядит следующим образом:
created () {
let users = Array.from({ length: 100000 }, (item, index) => ({ name: index }))
this.users = Object.freeze(users)
}
Нажмите кнопку «Перезагрузить» еще раз, чтобы повторно протестировать производительность.
В настоящее время,Hello.vue
компонентыrender
&patch
Время:
- рендеринг -> 397 мс (результат последнего теста: 924 мс, экономия времени: 527 мс, улучшение производительности около 57%)
- патч -> 782 мс (результат последнего теста: 1440 мс, экономия времени: 658 мс, улучшение производительности: 45,7%)
Проверено только один раз здесь, но из результатов, увеличиваясьObject.freeze
После заморозки общая производительность значительно улучшится.
3. Создать магазин без Vuex (Vue.observable)
2.6.0 Новый
- Параметры: объект {Object}
- Использование: Сделать объект отзывчивым. Он используется внутри Vue для обработки объекта, возвращаемого функцией данных.
Возвращенный объект можно использовать непосредственно в функциях рендеринга и вычисляемых свойствах, и он будет запускать соответствующие обновления, когда что-то изменится. Также может использоваться как минимальное межкомпонентное хранилище состояний для простых сценариев:
const state = Vue.observable({ count: 0 })
const Demo = {
render(h) {
return h('button', {
on: { click: () => { state.count++ }}
}, `count is: ${state.count}`)
}
}
Мы можем использовать эту API для решения ситуации несколько простых перекрестных данных обмена данными.
// miniStore.js
import Vue from "vue";
export const miniStore = Vue.observable({ count: 0 });
export const actions = {
setCount(count) {
miniStore.count = count;
}
}
export const getters = {
count: () => miniStore.count
}
// Demo.vue
<template>
<div>
<p>count:{{count}}</p>
<button @click="add"> +1 </button>
<button @click="sub"> -1 </button>
</div>
</template>
<script>
import { actions, getters } from "./store";
export default {
name: "App",
computed: {
count() {
return getters.count;
}
},
methods: {
add: actions.setCount(this.count+1),
sub: actions.setCount(this.count-1)
}
};
</script>
4. Доставка атрибутов и событий
пишуVue
компонентов, часто встречаются:
- Послойный перенос компонентов
props
илиlisterers
- динамическая привязка
props
илиlisterers
Есть ли способ решить два вышеуказанных сценария?
::: tip
v-bind
а такжеv-on
, может решить вышеуказанные проблемы
:::
Пример кода выглядит следующим образом:
<template>
<Child v-bind="$props" v-on="$listeners"> </Child>
</template>
<script>
import Child from "./Child";
export default {
props: {
title: {
required: true,
type: String
}
}
components: {
Child
}
};
</script>
5. Функция жизненного цикла функции слушателя
Иногда необходимо прослушать родительский компонент после монтирования дочернего компонента.mounted
, выполните некоторую логическую обработку.
Например:
При загрузке удаленного компонента требуется время, чтобы зафиксировать компонент от удаленной загрузки до монтажа.
На данный момент вы не можете использовать обычный метод записи для перехода к каждому подкомпоненту.this.$emit
мероприятие.
Есть ли способ просто прослушать функцию ловушки жизненного цикла каждого дочернего компонента в родительском компоненте?
::: tip
@hook
Вы можете прослушивать хуки жизненного цикла дочерних компонентов (created
, updated
так далее).
Например:@hook:mounted="doSomething"
:::
// Parent.vue
<template>
<Child v-bind="$props" v-on="$listeners" @hook:mounted="doSomething"> </Child>
</template>
<script>
import Child from "./Child";
export default {
props: {
title: {
required: true,
type: String
}
}
components: {
Child
},
methods: {
doSomething(){
console.log("child component has mounted!");
}
}
};
</script>
6. Функциональные компоненты
::: наконечник Функциональные компоненты не имеют состояния, не могут быть созданы и не имеют внутренних методов обработки жизненного цикла.Они очень легкие и имеют высокую производительность рендеринга.Они особенно подходят для компонентов, которые зависят только от внешней передачи данных. :::
Это написано следующим образом:
- отмечено в теге шаблона
functional
- Принимает только значения реквизита
- Теги сценария не требуются
<!-- App.vue -->
<template>
<div>
<UserList :users="users" :click-handler="clickHandler.bind(this)"></UserList>
</div>
</template>
<script>
import UserList from "./UserList";
export default {
name: "App",
data: () => {
users: ['james', 'ian']
}
components: { UserList },
methods: {
clickHandler(name){
console.log(`clicked: ${name}`);
}
}
};
</script>
// UserList.vue
<template functional>
<div>
<p v-for="(name, idx) in props.users" @click="props.clickHandler(name)" :key="idx">
{{ name }}
</p>
</div>
</template>
7. Слоты с заданной областью действия
В версии 2.6.0 Vue представил новый унифицированный синтаксис для именованных слотов и слотов с ограниченной областью действия (например, директиву v-slot). Он заменяет слот и слот-область, две функции, которые в настоящее время устарели, но не удалены и все еще находятся в документации. Происхождение нового синтаксиса можно найти в этом RFC.
Простой пример
Как использовать Scoped Slots? Пожалуйста, смотрите следующий пример:
<template>
<List :items="items">
<template slot-scope="{ filteredItems }">
<p v-for="item in filteredItems" :key="item">{{ item }}</p>
</template>
</List>
</template>
использоватьv-slot
, вы можете написать значение слота прямо на этикетке компонентаscope
.
<template>
<List v-slot="{ filteredItems }" :items="items">
<p v-for="item in filteredItems" :key="item">{{ item }}</p>
</List>
</template>
::: tip
v-slot
только в компонентах илиtemplate
Он используется в тегах, но не может использоваться в обычных HTML-тегах.
:::
Это делает код более читаемым, особенно в сценариях, где трудно сказать, откуда берутся переменные шаблона.
Расширенное использование v-slot
v-slot
Директивы также вводят способ объединенияslot
&scoped-slot
, но должны быть разделены ":".
<template>
<Promised :promise="usersPromise">
<p slot="pending">Loading...</p>
<ul slot-scope="users">
<li v-for="user in users">{{ user.name }}</li>
</ul>
<p slot="rejected" slot-scope="error">Error: {{ error.message }}</p>
</Promised>
</template>
использоватьv-slot
Переписать:
<template>
<Promised :promise="usersPromise">
<template v-slot:pending>
<p>Loading...</p>
</template>
<template v-slot="users">
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</template>
<template v-slot:rejected="error">
<p>Error: {{ error.message }}</p>
</template>
</Promised>
</template>
v-slot
также может быть сокращено как#
, переписав приведенный выше пример:
<template>
<Promised :promise="usersPromise">
<template #pending>
<p>Loading...</p>
</template>
<template #default="users">
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</template>
<template #rejected="error">
<p>Error: {{ error.message }}</p>
</template>
</Promised>
</template>
::: наконечник
Уведомление,v-slot
Аббревиатура#default
:::
8. watch
несмотря на то чтоVue.js
предоставляет нам полезныеcomputed
, но в некоторых случаях все же необходимо использоватьwatch
.
::: наконечник
по умолчанию,watch
Выполняется только при изменении значения отслеживаемого свойства.
:::
Например:
export default {
data: () => ({
dog: ""
}),
watch: {
dog(newVal, oldVal) {
console.log(`Dog changed: ${newVal}`);
}
}
};
Как показано в приведенном выше коде, только когдаdog
При изменении значенияwatch
серединаdog
функция выполнится.
Однако в некоторых случаях может потребоваться запустить прослушиватель сразу после создания компонента.
Конечно, вы можете перенести логику наmethods
, то изwatch
а такжеcreated
Он вызывается отдельно в функции хука, но есть ли более простой способ?
вы можете использоватьwatch
когда используешьimmediate: true
вариант, чтобы он выполнялся, как только компонент будет создан.
export default {
data: () => ({
dog: ""
}),
watch: {
dog: {
handler(newVal, oldVal) {
console.log(`Dog changed: ${newVal}`);
},
immediate: true
}
}
};
9. Ленивая загрузка изображения
v-lazy-imageКомпонент ленивой загрузки изображения.
Установить:npm install v-lazy-image
использовать:
// main.js
import Vue from "vue";
import { VLazyImagePlugin } from "v-lazy-image";
Vue.use(VLazyImagePlugin);
<template>
<v-lazy-image src="http://lorempixel.com/400/200/" />
</template>
Вы также можете использовать прогрессивную загрузку изображений для загрузки изображений, установивsrc-placeholder
Миниатюры загружаются первыми, при этом применяются собственные эффекты фильтрации с помощью CSS.
<template>
<v-lazy-image
src="http://demo.com/demo.jpeg"
src-placeholder="http://demo.com/min-demo.jpeg"
/>
</template>
<style scoped>
.v-lazy-image {
filter: blur(10px);
transition: filter 0.7s;
}
.v-lazy-image-loaded {
filter: blur(0);
}
</style>
10. Модификатор .sync
2.3.0+ Новый
В некоторых случаях нам может понадобитьсяprop
Делайте «двустороннюю привязку».
К сожалению, истинное двустороннее связывание создает проблемы сопровождения, поскольку дочерние компоненты могут изменять родительский компонент, а очевидных источников изменений как в родительском, так и в дочернем компонентах нет.
Вот почему мы рекомендуемupdate:myPropNameСобытие модального триггера заменено.
Например, в содержащемtitle
В компоненте свойства prop мы можем выразить намерение присвоить ему новое значение следующими способами:
this.$emit('update:title', newTitle)
Затем родительский компонент может прослушивать это событие и при необходимости обновлять локальное свойство данных. Например:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
Для удобства приведем аббревиатуру этого режима, а именно.sync
Модификатор:
<text-document v-bind:title.sync="doc.title"></text-document>
::: Опасность
с участием.sync
модификаторv-bind
Нельзя использовать с выражениями.
Например: v-bind:title.sync="doc.title + ‘!’” недействителен.
Вместо этого вы можете указать только имя свойства, которое хотите связать, аналогично v-model. :::
Когда мы используем один объект для установки нескольких одновременноprop
, вы также можете использовать это.sync
модификаторы иv-bind
С использованием:
<text-document v-bind.sync="doc"></text-document>
Это передаст каждое свойство (например, заголовок) в объекте документа как отдельную опору, а затем добавит каждое свойство для обновления.v-onслушатель.
Уведомление
Будуv-bind.syncИспользуется на буквальном объекте.
Например:v-bind.sync=”{ title: doc.title }”
, не работает должным образом.
Потому что при синтаксическом анализе такого сложного выражения необходимо учитывать множество пограничных случаев.
11. provide / inject
2.2.0 Новый
Типы:
- обеспечить: Объект | () => Объект
- inject: Массив | { [ключ: строка]: строка | Символ | Объект }
Примечание: предоставление и внедрение в основном предоставляют варианты использования для библиотек плагинов/компонентов более высокого порядка. Его не рекомендуется использовать непосредственно в коде приложения.
Эту пару опций необходимо использовать вместе, чтобы позволить компоненту-предку внедрить зависимость во все его потомки, независимо от того, насколько глубока иерархия компонентов, и она всегда будет действовать, пока устанавливаются отношения восходящего и нисходящего потоков. Если вы знакомы с React, это похоже на контекстные функции React.
Параметр предоставления должен быть объектом или функцией, которая возвращает объект. Этот объект содержит свойства, которые можно внедрить в его потомков. Вы можете использовать символы ES2015 в качестве ключей в этом объекте, но это будет работать только в средах, изначально поддерживающих символы и Reflect.ownKeys.
Вариант инъекции должен быть:
- массив строк или
- Объект, ключ которого является именем и значением локальной привязки:
- Ключ (строка или символ) для поиска в доступном внедряемом контенте или
- Объект, который:
- Свойство from — это ключ (строка или символ) для поиска в доступном внедряемом содержимом.
- Атрибут по умолчанию — это значение, используемое в случае перехода на более раннюю версию.
Совет: привязки обеспечить и внедрить не являются реактивными. Это сделано намеренно. Однако, если вы передаете прослушиваемый объект, свойства объекта по-прежнему реагируют.
Пример:
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
// ...
}
Воспользуйтесь преимуществами символов ES2015, предоставления функций и внедрения объектов:
const s = Symbol()
const Provider = {
provide () {
return {
[s]: 'foo'
}
}
}
const Child = {
inject: { s },
// ...
}
Внедрение в 2.5.0+ можно сделать необязательным, установив значение по умолчанию:
const Child = {
inject: {
foo: { default: 'foo' }
}
}
Если его необходимо внедрить из свойства с другим именем, используйте from для обозначения исходного свойства:
const Child = {
inject: {
foo: {
from: 'bar',
default: 'foo'
}
}
}
Подобно значениям по умолчанию для реквизита, вам нужно использовать фабричный метод для непримитивных значений:
const Child = {
inject: {
foo: {
from: 'bar',
default: () => [1, 2, 3]
}
}
}
12. Отладка шаблона Vue
В процессе разработки Vue вы часто сталкиваетесь с проблемой ошибок переменных JavaScript при рендеринге шаблона шаблона.В это время вы можете передатьconsole.log
Для примера отладки:
<template>
<h1>
{{ log(message) }}
</h1>
</template>
<script>
methods: {
log(message) {
console.log(message);
}
}
</script>
Каждый раз, когда я отлаживаю рендеринг шаблона, может быть скучно писать так постоянно, есть ли лучший способ?
существуетVue.prototype
Добавьте пользовательский метод в цепочку прототипов.
// main.js
Vue.prototype.$log = window.console.log;
Пока что мы можем использовать в шаблоне каждого компонента$log
, если мы не хотим влиять на отрисовку шаблона, мы также можем:
<h1>
{{ log(message) || message }}
</h1>
Разве это не очень удобно для отладки шаблонов?
Это расширение, есть ли способ добавить точку останова, чтобы увидеть связанную переменную при отладке шаблона рендеринга?
Мы положили один при использовании шаблоновdebugger
.
<h1>
{{ debugger }}
</h1>
Вы обнаружите, что компонент вообще не компилирует шаблон, есть ли способ?
Мы можем попробовать добавить в шаблон самовыполняющуюся функцию, например:
<h1>
{{ (function(){degugger;}) || message }}
</h1>
На данный момент мы видим, что точка останова находится в функции рендеринга шаблона.
В настоящее время_vm
, является экземпляром объекта нашего компонента.
Интересно проверить скомпилированный шаблон, но почему-то переменная помещается вdebugger
становится недоступным в рамках функций chrome devtools.
Измените написание ниже:
<h1>
{{ (function(){degugger; message}) || message }}
</h1>
В этот момент вы можете делать все, что хотите.
13. Локальный стиль компонента Vue с областью действия
Атрибут scoped тега стиля в Vue указывает, что его стиль влияет только на текущий модуль, т.е.стиль приватизации, Первоначальная цель дизайна - сделать стиль неизменяемым.
Правила/принципы рендеринга:
- Добавьте уникальный атрибут данных в узел HTML DOM, чтобы указать уникальность
- Добавьте селектор атрибутов данных текущего компонента в конец соответствующего селектора CSS, чтобы приватизировать стиль, например: .demo[data-v-2311c06a]{}
- Если компонент содержит другие компоненты, он добавит только атрибут data-v текущего компонента к самым внешним тегам других компонентов.
Например, как показано в следующем коде:
<template>
<div class="demo">
<span class="content">
Vue.js scoped
</span>
</div>
</template>
<style lang="less" scoped>
.demo{
font-size: 14px;
.content{
color: red;
}
}
</style>
Код после рендеринга в браузере:
<div data-v-fed36922>
Vue.js scoped
</div>
<style type="text/css">
.demo[data-v-039c5b43] {
font-size: 14px;
}
.demo .content[data-v-039c5b43] {
color: red;
}
</style>
::: подсказка Примечание После добавления атрибута области действия родительский компонент не может изменить стиль дочернего компонента. :::
14. Глубокий селектор стиля компонента Vue
В приведенном выше примере, что мне делать, если я хочу изменить стиль дочернего компонента в родительском компоненте?
- 1. Используйте комбинацию глобальных атрибутов и локальных атрибутов
- 2. Каждый компонент добавляет уникальный класс к самому внешнему слою, чтобы различать разные компоненты.
- 3. Используйте глубокий селектор
Здесь мы в основном объясняем использованиеdeep
Измените стиль дочернего компонента.Измените код приведенного выше примера на:
<template>
<div class="demo">
<span class="content">
Vue.js scoped
</span>
</div>
</template>
<style lang="less" scoped>
.demo{
font-size: 14px;
}
.demo /deep/ .content{
color: blue;
}
</style>
Результат окончательной компиляции стиля:
<style type="text/css">
.demo[data-v-039c5b43] {
font-size: 14px;
}
.demo[data-v-039c5b43] .content {
color: blue;
}
</style>
Как видно из компиляции,.content
Добавлять ли свойства CSS послеdata-v-xxx
Разница, одноклассники атрибута селектора CSS проблема веса, должны сразу это понять!
15. Модули локального стиля компонента Vue
CSS Modules — это популярная система модульного построения и комбинирования CSS.vue-loader
Обеспечивает первоклассную интеграцию с модулями CSS, доступными в виде макета.scoped CSS
альтернатива.
Применение
Во-первых, модули CSS должны пройтиcss-loader
входящийmodules: true
включать:
// webpack.config.js
{
module: {
rules: [
// ... 其它规则省略
{
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// 开启 CSS Modules
modules: true,
// 自定义生成的类名
localIdentName: '[local]_[hash:base64:8]'
}
}
]
}
]
}
}
тогда в вашем<style>
Добавьте функцию модуля в:
<style module>
.red {
color: red;
}
.bold {
font-weight: bold;
}
</style>
Эта функция модуля направляет Vue Loader как вычислительное свойство с именем $ STYLE, внедряет частичный объект модулей CSS в компонент. Затем вы можете использовать привязку динамического класса в шаблоне:
<template>
<p :class="$style.red">
This should be red
</p>
</template>
Поскольку это вычисляемое свойство, оно также поддерживает:class
Синтаксис объекта/массива:
<template>
<div>
<p :class="{ [$style.red]: isRed }">
Am I red?
</p>
<p :class="[$style.red, $style.bold]">
Red and bold
</p>
</div>
</template>
Вы также можете получить к нему доступ через JavaScript:
<script>
export default {
created () {
console.log(this.$style.red)
// -> "red_1VyoJ-uZ"
// 一个基于文件名和类名生成的标识符
}
}
</script>
Вы можете обратиться к спецификации модулей CSS для получения более подробной информации, напримерglobal exceptions
а такжеcomposition
Ждать.
необязательное использование
Если вы просто хотите использовать модули CSS в некоторых компонентах Vue, вы можете использовать правила ONEOF и проверьте строку модуля в строке RectionQuery:
// webpack.config.js -> module.rules
{
test: /\.css$/,
oneOf: [
// 这里匹配 `<style module>`
{
resourceQuery: /module/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]_[hash:base64:5]'
}
}
]
},
// 这里匹配普通的 `<style>` 或 `<style scoped>`
{
use: [
'vue-style-loader',
'css-loader'
]
}
]
}
Использовать с препроцессором
Модули CSS можно использовать с другими препроцессорами:
// webpack.config.js -> module.rules
{
test: /\.scss$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: { modules: true }
},
'sass-loader'
]
}
пользовательское имя инъекции
В .vue вы можете определить более одного<style>
, чтобы избежать перезаписи, вы можете определить для них имя внедренного вычисляемого свойства, установив атрибут модуля.
<style module="a">
/* 注入标识符 a */
</style>
<style module="b">
/* 注入标识符 b */
</style>
16. Всегда проверяйте реквизиты
Проверка свойств — это базовая практика в Vue. Возможно, вы знаете, как выполнить проверку некоторых примитивных типов данных, таких как: String, Number и т. д. Конечно, вы также можете настроить функцию проверки, например:
props: {
name: {
type: String,
required: true,
validator: function(value) {
return [
'张三',
'李四',
'王五'
].indexOf(value) !== -1
}
}
}
17. Пользовательская v-модель
по умолчанию,v-model
да@input
прослушиватели событий и:value
Синтаксический сахар для свойств.Однако вы также можете указать свойство модели в своем компоненте Vue, чтобы определить, что такое события и свойства значений.
export defaut {
model: {
event: 'change',
prop: 'checked'
}
}
18. Параметры динамической команды
2.6+ Новый Vue 2.6 может динамически передавать параметры директивы компонентам.Например, если у вас есть компонент кнопки, и в некоторых случаях вам нужно прослушивать события щелчка, а в некоторых случаях вам нужно прослушивать события двойного щелчка, вы можете написать :
<template>
<div>
<div>hellojames</div>
<button v-on:[eventType]="eventHandler($event)">xxx</button>
</div>
</template>
<script>
export default {
data () {
return {
someCondition: 1
}
},
computed: {
eventType () {
return this.someCondition ? 'click' : 'dblclick'
}
},
methods: {
eventHandler ($event) {
// todo something
window.console.log($event)
}
}
}
</script>
Таким образом, вы можете применить один и тот же шаблон к динамическим HTML-атрибутам, свойствам и т. д.