1. scoped的原理
vue中的 scoped
通过在DOM结构以及css样式上加唯一不重复的标记:data-v-hash
的方式,以保证唯一(而这个工作是由过PostCSS转译实现的),达到样式私有化模块化的目的。
总结一下scoped三条渲染规则:
- 给HTML的DOM节点加一个不重复
data
属性(形如:data-v-123)来表示他的唯一性 - 在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-123])来私有化样式
- 如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性
2. :deep()
:deep()
:改变css解析时私有属性的位置
常见作用场景:修改组件库样式
<template>
<div class="outer">
<el-input></el-input>
</div>
</template>
<style lang="less" scoped>
.outer {
.el-input__inner {
// 此时css解析的为 .outer .el-input__inner[data-v-xxxx] 样式无效
background: pink;
}
:deep(.el-input__inner) {
// 此时css解析的为 .outer[data-v-xxxx] .el-input__inner 样式生效
background: red;
}
}
</style>
3. :slotted()
:slotted()
:在子组件定义样式插槽内容样式
默认情况下,作用域样式不会影响到 <slot/>
渲染出来的内容,因为它们被认为是父组件所持有并传递进来的。
<template>
<div>
<slot>插槽</slot>
</div>
</template>
<style lang="less" scoped>
:slotted(.red) {
color: red;
}
</style>
4. :global()
:global()
:全局选择器,定义全局样式,不用单开一个没有scoped
的style
<style scoped>
:global(div) {
color: red;
}
</style>
<!-- 等效于 -->
<style>
div{
color:red
}
</style>
5. 动态css(v-bind)
<script setup lang="ts">
const redColor = ref('red')
const color = ref({
red: 'red',
green: 'green'
})
</script>
<style lang="less" scoped>
.box {
color: v-bind(redColor);
background: v-bind('color.green'); // 对象要加 ''
}
</style>
6. css module
常用场景:一般用于TSX和渲染函数
<style module>
标签会被编译为 CSS Modules 并且将生成的 CSS 类作为 $style
对象的键暴露给组件
<template>
<div :class="$style.red">
文字
</div>
</template>
<style module>
.red {
color: red;
font-size: 20px;
}
</style>
自定义注入名称(多个可以用数组)
<template>
<div :class="[dd.box,dd.f]">
文字
</div>
</template>
<script setup lang="ts">
import { useCssModule } from 'vue'
const css = useCssModule('dd')
</script>
<style module="dd">
.box{
color: red;
font-size: 20px;
}
.f{
background: green;
}
</style>