Shadow DOM — это технология веб-компонентов, позволяющая создавать инкапсулированные DOM-деревья с собственными стилями и скриптами. В контексте Vue.js Shadow DOM может применяться для повышения изоляции компонентов, предотвращения конфликтов CSS и управления внутренними состояниями компонентов без влияния глобального окружения.
Инкапсуляция Shadow DOM создаёт отдельное DOM-дерево, привязанное к элементу-хосту. Внутренние элементы Shadow DOM изолированы от внешнего DOM, что означает:
::part или ::slotted;composed: true).Элементы-хосты Любой HTML-элемент может стать
хостом Shadow DOM, используя метод
attachShadow({ mode: 'open' }) или
attachShadow({ mode: 'closed' }). В Vue.js это применяется
через кастомные компоненты с опцией shadow: true.
Стили и скопированные CSS CSS внутри Shadow DOM не конфликтует с глобальными стилями. Для передачи стилей из внешнего окружения используются:
--variable)<slot> для вставки внешнего контента.Vue.js начиная с версии 3 поддерживает создание компонентов с Shadow
DOM через опцию customElement или
shadow: true.
Пример базового компонента с Shadow DOM:
import { defineComponent, h } from 'vue';
export default defineComponent({
name: 'ShadowButton',
shadow: true,
render() {
return h('button', { class: 'shadow-btn' }, 'Кнопка');
}
});
shadow: true создаёт инкапсулированный DOM для
компонента.<style scoped> или через <style>
внутри <template>.Shadow DOM поддерживает слоты, что позволяет внедрять контент из родительского компонента без разрушения инкапсуляции.
<template>
<div>
<slot name="header"></slot>
<p>Основной контент компонента</p>
<slot></slot>
</div>
</template>
<script>
export default {
shadow: true
}
</script>
<style scoped>
p {
color: blue;
}
</style>
<slot> или
<slot name="header">, рендерится внутри Shadow DOM,
сохраняя инкапсуляцию стилей.--custom-property для стилизации слотов.События
composed: true
при создании события:this.$el.dispatchEvent(new CustomEvent('clicked', { bubbles: true, composed: true }));
Доступ к элементам
this.$refs для
доступа к элементам Shadow DOM.shadowRoot.querySelector.Важное отличие: глобальные стили не применяются. Для управления стилями:
<style scoped> автоматически помещает стили внутрь
Shadow DOM:<style scoped>
button {
background-color: red;
}
</style>
<style scoped>
p {
color: var(--text-color, black);
}
</style>
<slot>, можно использовать псевдокласс
::slotted:<style scoped>
::slotted(span) {
font-weight: bold;
}
</style>
defineCustomElement компоненты Vue можно экспортировать как
нативные Web Components с Shadow DOM.vite или webpack необходимо
настроить правильную обработку стилей для
shadow: true.Использование Shadow DOM в Vue.js позволяет создавать
инкапсулированные, независимые компоненты с чистыми стилями и
предсказуемым поведением. Комбинация слотов, CSS-переменных и событий с
composed: true обеспечивает гибкость взаимодействия с
внешним окружением при сохранении полной изоляции внутренней структуры
компонента.