文章目录
- 样式穿透:deep()
- scoped的原理
- 插槽选择器:slotted()
- 全局选择器:global()
- 动态绑定CSS
- css module
样式穿透:deep()
主要是用于修改很多vue常用的组件库(element, vant, AntDesigin),虽然配好了样式但是还是需要更改其他的样式就需要用到样式穿透。
scoped的原理
vue
中的scoped
通过在DOM
结构以及css
样式上加唯一不重复的标记:data-v-hash的方式,以保证唯一(而这个工作是由过PostCSS
转译实现的),达到样式私有化模块化的目的。
scoped三条渲染规则:
- 给HTML的DOM节点加一个不重复data属性(形如:data-v-123)来表示他的唯一性
- 在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-123])来私有化样式
- 如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性
这是组件内部包含有其他组件的情况(当前.vue文件也是一个组件),只会给其他组件的最外层标签加上当前组件的data属性
如果不写Scoped 就没问题
原因就是Scoped 搞的鬼 他在进行PostCss转化的时候把元素选择器默认放在了最后。
上面提到第三条的规则 因为当前组件标签是没有这个属性标签的,所以无法修改样式。
Vue 提供了样式穿透 /deep/(vue2写法) :deep()(vue3写法)
他的作用就是用来改变 属性选择器的位置
:deep()原理很简单,就是将属性标签提到外层。
插槽选择器:slotted()
使用场景:在使用插槽组件的时候写样式,默认不会影响 <slot/>
渲染出来的内容,因为它们被认为是父组件所持有并传递进来的。
<template>
<div>
<A>
<div class="a">私人定制div</div>
</A>
</div>
</template>
<script setup>
import A from "@/components/A.vue"
</script>
<style lang="less" scoped>
</style>
<template>
<div>
我是插槽
<slot></slot>
</div>
</template>
<script>
export default {}
</script>
<style scoped>
.a{
不会生效的
color:red
}
这样就可以修改父组件中定义的.a的样式
:slotted(.a) {
color:red
}
</style>
全局选择器:global()
在之前我们想加入全局 样式 通常都是新建一个style
标签 不加scoped
现在有更优雅的解决方案
<style>
div{
color:red
}
</style>
<style lang="less" scoped>
</style>
使用全局选择器
<style lang="less" scoped>
:global(div){
color:red
}
</style>
动态绑定CSS
单文件组件的 <style>
标签可以通过 v-bind
这一 CSS
函数将 CSS
的值关联到动态的组件状态上:
<template>
<div class="div">
红色
</div>
<div class="pink">
粉色
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const red = ref<string>('red')
setTimeout(()=>{
red.value = 'blue'
},2000)
const pink= ref({
color:'pink'
})
</script>
<style lang="less" scoped>
.div{
color:v-bind(red)
}
.pink{
对象形式需要使用单引号
color:v-bind('pink.color')
}
</style>
css module
<style module>
标签会被编译为 CSS Modules
并且将生成的 CSS
类作为 $style
对象的键暴露给组件
<template>
<div :class="$style.red">
11111
</div>
</template>
<style module>
.red {
color: red;
font-size: 20px;
}
</style>
自定义注入名称(多个可以用数组)
<template>
这里可以使用数组的形式添加多个
<div :class="[zs.red,zs.border]">
111
</div>
</template>
这里自定义了名称为zs
<style module="zs">
.red {
color: red;
font-size: 20px;
}
.border{
border: 1px solid #ccc;
}
</style>
与组合式 API 一同使用
注入的类可以通过 useCssModule API
在 setup()
和 <script setup>
中使用。对于使用了自定义注入名称的 <style module>
模块,useCssModule
接收一个对应的 module attribute
值作为第一个参数(了解即可 不常用 一般用于jsx、render 函数中)
<template>
<div :class="[zs.red,zs.border]">
111
</div>
</template>
<script setup lang="ts">
import { useCssModule } from 'vue'
const css = useCssModule('zs')
console.log(css)
</script>
<style module="zs">
.red {
color: red;
font-size: 20px;
}
.border{
border: 1px solid #ccc;
}
</style>