如何让CSS像组件状态一样实现响应式更新呢?
不知道平时在项目里你怎么处理CSS呢?
我们知道,由于原生CSS存在一些问题,比如:
- 复用时容易样式冲突
- 没有作用域、没有模块化
- 没有编程能力
社区涌现出很多解决方案,比如:
- 命名规范(比如
BEM规范) - 模块规范(CSS Modules)
CSS预处理器(比如Less)CSS In JSCSS框架(Tailwind CSS)- ……
如果我们按以下三个维度评判这些方案:
- 上手难度:与原生
CSS越接近,越好上手 - 灵活性:拥有越强编程能力,越灵活
- 能力:能解决多少原生
CSS的问题
会发现每个方案都有自己的优势与短板。

比如:
CSS In JS方案用JS写CSS,拥有极高灵活性,但加大了上手难度Less(CSS预处理器)可以看作CSS的超集,上手难度低、有一定编程能力,但是CSS自身的问题他也存在
业界常见做法是:同时使用BEM规范(解决命名冲突问题)+ CSS预处理器。
进击的 Vue CSS 解决方案
我们用这三个维度分析下Vue的SFC(Single-File-Component,单文件组件):
<template>
<p>xxx</p>
</template>
<script>
// ...
</script>
<style scoped>
p {
color: #0f0;
}
</style>
- 上手难度:样式在
<style>标签内书写,与原生CSS别无二致,上手简单,符合直觉 - 能力:
scoped标识提供了模块化能力 - 灵活性:可以使用各种预处理器,有一定灵活性
可以看到,Vue SFC采用的是一种各方面没有明显短板,局部很突出(上手难度低)的CSS方案。
随着Vue 3.2 发布,Vue SFC中的CSS属性获得了响应式更新能力,使其灵活性大大提升。
响应式 CSS 属性
对于如下Vue SFC:
<template>
<div class="text">hello</div>
</template>
<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>
<style>
.text {
color: v-bind(color);
}
</style>
<script>标签内定义了状态color = 'red'
.text使用v-bind为color属性绑定该状态。效果如下:

为了验证响应式更新能力, 为div增加点击事件:
<div class="text" @click="color= color === 'red' ? 'green' : 'red'">hello</div>
点击后会让color状态在red与green间切换。可以看到,页面样式也会同步变化:

Demo 地址:点击这里
不仅是color,你可以为任何CSS属性绑定状态。
那么这个特性是如何实现的呢?
实现原理
每个使用v-bind绑定到CSS属性的状态对应一个CSS变量,该CSS变量会作为style属性赋值给组件最外层DOM。
在我们的例子中:
.text {
color: v-bind(color);
}
其中v-bind(color)会成为CSS变量:

并作为style属性赋值给div:

.text经过编译会使用该CSS变量:
.text {
// 编译前
/* color: v-bind(color); */
// 编译后
color: var(--469af010-color);
}
当颜色变化后,CSS变量的值随之变化:

所以,要使用这个特性需要目标浏览器支持CSS变量。

Vue3放弃IE这可是说到做到的。
总结
Vue官方称该特性为State-Driven Dynamic CSS。
经过这波操作,Vue SFC的CSS灵活性有了很大提高。
并且,有了v-bind这个开头,相信未来会出现更多与响应式更新挂钩的自定义 CSS 指令。
之前的自定义指令都是运行时的,以后的指令可能会是基于AST的编译时了。
以上关于如何让CSS像组件状态一样实现响应式更新呢?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 如何让CSS像组件状态一样实现响应式更新呢?

微信
支付宝