В Vue.js scoped стили по умолчанию не проникают в дочерние компоненты, но есть нюансы, которые важно понимать.
При использовании scoped
Vue добавляет уникальные data-атрибуты к элементам:
<!-- Исходный код -->
<style scoped>
.example { color: red; }
</style>
<template>
<div class="example">Текст</div>
</template>
<!-- Скомпилированный результат -->
<div class="example" data-v-f3f3eg9>Текст</div>
<style>
.example[data-v-f3f3eg9] { color: red; }
</style>
<!-- Parent.vue -->
<style scoped>
.child-class { color: red; } /* Не применится к ChildComponent */
</style>
<template>
<ChildComponent class="child-class"/>
</template>
Специальные синтаксисы для "пробрасывания" стилей:
<style scoped>
/* Старый синтаксис (Vue 2) */
.parent >>> .child { color: red; }
/* Синтаксис с /deep/ */
.parent /deep/ .child { color: red; }
/* Современный синтаксис (Vue 3) */
.parent :deep(.child) { color: red; }
</style>
Если класс добавлен в глобальном стиле, он будет работать:
<style>
/* Глобальный стиль */
.global-class { color: blue; }
</style>
<style scoped>
/* Локальный стиль */
.local-class { font-size: 16px; }
</style>
Некоторые свойства (например, color
, font-family
) наследуются естественным образом:
<style scoped>
.parent { color: green; } /* Текст в child будет зеленым */
</style>
<template>
<el-dialog class="my-dialog">
<!-- Содержимое -->
</el-dialog>
</template>
<style scoped>
/* Глубокий селектор для элементов библиотеки */
.my-dialog :deep(.el-dialog__title) {
color: var(--primary-color);
}
</style>
<style scoped>
/* Применится ко всем <p> внутри компонента, включая дочерние */
:deep(p) {
margin-bottom: 1em;
line-height: 1.5;
}
</style>
<style module>
.myClass { color: red; }
</style>
<ChildComponent :class="$style.myClass"/>
<style scoped>
.parent {
--text-color: #42b983;
}
.child {
color: var(--text-color);
}
</style>