Vue3 中的 CSS
功能
CSS
作用域
-
使用
scoped
后, 父组件的样式将不会渗透到子组件中. 不过子组件的根节点会同时被父组件的作用域样式
和子组件的作用域样式
影响. -
深度选择器
:deep()
-
处于
scoped
样式中的选择器如果要做更深度的选择, 即影响到子组件, 可以使用:deep
这个伪类 -
父组件
-
<div class="test"> <h3>Father-h3</h3> <Son></Son> </div>
-
<style scoped> .test h3 { background-color: #2ecc71; } .test h2 { background-color: #2ecc71; } </style>
-
-
子组件
-
<div> <h3>Son-h3</h3> <h2>Son-h2</h2> </div>
-
-
只有父组件的
<h3>
背景颜色发生了改变 -
如果修改父组件中的代码
-
.test :deep(h3) { background-color: #2ecc71; }
-
-
📕通过
-
-
插槽选择器
:slotted()
-
默认情况下, 作用域样式不会影响到
<slot/>
渲染出来的内容, 因为他们被认为是父组件所持有并传递进来的 -
父组件
-
<Son> <h4>哈哈哈,我是父组件传入的数据</h4> </Son>
-
-
子组件
-
<div> <h3>Son-h3</h3> <h2>Son-h2</h2> <slot></slot> </div>
-
<style scoped> h4 { background-color: #e67e22; } </style>
-
-
如下图, 传入
<slot>
的<h4>
元素背景颜色并没有发生改变 -
修改子组件, 使用
:slotted
选择器-
:slotted(h4) { background-color: #e67e22; }
-
-
-
全局选择器
:global()
- 如果想让一个样式规则应用到全局, 有两种方式
- 第一, 创建两个
<style>
节点, 一个全局, 一个局部 - 第二, 使用
:global()
选择器
- 第一, 创建两个
- 父组件
-
<div class="red">Father-red</div>
-
- 子组件
-
<div class="red">Son-red</div>
-
:global(.red) { background-color: #e74c3c; }
-
- 如果想让一个样式规则应用到全局, 有两种方式
-
作用域样式提示
- 作用域样式并没有消除对
class
的需求. 由于浏览器渲染各种各样CSS
选择器的方式,p
标签选择器结合作用域样式(属性选择器)会慢很多, 如果使用类选择器或者id
选择器就几乎可以避免性能的损失.
- 作用域样式并没有消除对
CSS Module
-
一个
<style module>
标签会被编译为CSS Modules
并且将生成的CSS class
作为$style
对象暴露给组件.- 关于 css-modules 看这里. 一个
CSS Module
就是一个CSS
文件, 这个文件中所有的class
名和animation
名都只能局部使用. -
<div :class="$style.yellow">Yellow by Coldplay</div> <div :class="$style.yellowWhite">Yellow by Coldplay</div>
-
<style module> .yellow { background-color: #f1c40f; } .yellow-white { background-color: #f1c40f; color: #fff; } </style>
- 关于 css-modules 看这里. 一个
-
注入自定义的名字
-
<style module="levi"> .yellow { background-color: #f1c40f; } </style>
-
<div :class="levi.yellow">Yellow by Coldplay</div>
-
-
与组合式
API
一同使用- 可以通过
useCssModule
API
在setup
或者<script setup>
中访问注入的class
, 对于使用自定义诸如名称的module
, 在调用useCssModule
时需要接收一个新的参数. -
<script setup> import { useCssModule } from 'vue' // 没有起别名 // const module = useCssModule(); const levi = useCssModule('levi'); console.log('levi', levi) </script>
- 可以通过
CSS 中的 v-bind
-
但文件中的
<style>
标签支持使用v-bind
CSS
函数将CSS
的值链接到组件的状态- 📕如果访问对象属性, 需要使用引号
-
<div class="what">What R U Doing now?</div>
-
<script setup> import { reactive } from 'vue'; let theme = reactive({ color: '#9b59b6', }) let fontColor = '#fff'; </script>
-
.what { background-color: v-bind('theme.color'); color: v-bind(fontColor); }
-
实际的值会被编译成哈希化的
CSS
自定义property
, 因此CSS
本身仍然是静态的.-
自定义
property
会通过内联样式的方式应用到组件的根元素上, 并且在源值变更的时候响应式地更新 -
<button @click="changeBgColor">changeBgColor</button>
-
function changeBgColor() { theme.color === '#9b59b6' ? theme.color = '#1abc9c' : theme.color = '#9b59b6'; }