<style scoped>
- 当
<style>
标签带有 `scoped
` attribute 的时候,它的CSS
只会应用到当前组件的元素上。 - 子组件的根元素:
- 子组件的根节点会同时被父组件的作用域样式和子组件的作用域样式影响。这是有意为之的,这样父组件就可以设置子组件根节点的样式,以达到调整布局的目的。
- 如果使用了片段(多根节点)功能的子组件,则无效。
- 只有1个根节点的子组件,父组件对子组件标签设置 style 时,根节点会有例如:<div data-v-kumiko147 data-v-kumiko258> 2个不同的唯一属性
- 片段特性的子组件,则只会有1个。[ 不会有父组件的 style scoped 的唯一标识 ]
<style scoped>
.example {
color: red;
}
</style>
// 编译后
.example[data-v-kumiko147] {
color: red;
}
深度选择器
- 处于 scoped 样式中的选择器如果想要做更“深度”的选择,也即:影响到子组件,可以使用 :deep() 这个伪类
<style scoped>
.a :deep(.b) {
/* ... */
}
</style>
// 编译后
.a[data-v-f3f3eg9] .b {
/* ... */
}
- 通过 v-html 创建的 DOM 内容不会被作用域样式影响,但你仍然可以使用深度选择器来设置其样式。
- 并且我们有时会有需要修改引入的外部组件库的样式的需求,此时就需要使用深度选择器,或者直接<style>不加scoped,作用于全局范围。
插槽选择器
- 默认情况下,作用域样式不会影响到
<slot/>
渲染出来的内容,因为它们被认为是父组件所持有并传递进来的。使用:slotted
伪类以确切地将插槽内容作为选择器的目标:
<style scoped>
:slotted(div) {
color: red;
}
</style>
全局选择器
- 如果想让其中一个样式规则应用到全局,比起另外创建一个
<style>
,可以使用:global
伪类来实现 (看下面的代码):
<style scoped>
:global(.red) {
color: red;
}
</style>
// 等同于
<style>
.red{
color: red;
}
:global(.red){} // 这是错误的,不会生效
</style>
!! 注意::global 直接用在 <style> 内无效!
混合使用局部与全局样式
你也可以在同一个组件中同时包含作用域样式和非作用域样式:
<style>
/* global styles */
</style>
<style scoped>
/* local styles */
</style>
状态驱动的动态 CSS : v-bind()
- 单文件组件的
<style>
标签可以通过v-bind
这一 CSS 函数将 CSS 的值关联到动态的组件状态上:
<script setup>
import {ref} from 'vue'
let colorData = ref('red')
</script>
<style>
.testClass2{
color: v-bind(colorData);
}
</style>
<style scoped>
.testClass{
color: v-bind(colorData);
}
</style>
非script setup语法糖的例子就不写了,这还用写吗...
<style module>
<style module>
标签会被编译为 CSS Modules 并且将生成的 CSS 类作为$style
对象的键暴露给组件:
<template>
<p :class="$style.red">
This should be red
</p>
</template>
<style module>
.red {
color: red;
}
</style>
- 自定义注入名称
- 你可以通过给
module
attribute 一个值来自定义注入的类对象的property
键:
- 你可以通过给
<template>
<p :class="classes.red">red</p>
</template>
<style module="classes">
.red {
color: red;
}
</style>
- 与组合式 API 一同使用
注入的类可以通过useCssModule
API 在 setup() 和<script setup>
中使用。对于使用了自定义注入名称的<style module>
模块,useCssModule
接收一个对应的module
attribute 值作为第一个参数。
<script>
// 默认, 返回 <style module> 中的类
useCssModule()
// 命名, 返回 <style module="classes"> 中的类
useCssModule('classes')
</script>
还有一件事
-
Scoped 样式不能代替 class。考虑到浏览器渲染各种 CSS 选择器的方式,当
p { color: red }
是 scoped 时 (即与特性选择器组合使用时) 会慢很多倍。如果你使用 class 或者 id 取而代之,比如.example { color: red }
,性能影响就会消除。 -
在递归组件中小心使用后代选择器! 对选择器
.a .b
中的 CSS 规则来说,如果匹配.a
的元素包含一个递归子组件,则所有的子组件中的.b
都将被这个规则匹配。