CSS也能像组件状态一样响应式更新?

开发 前端
层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。

[[417025]]

大家好,我是卡颂。

不知道平时在项目里你怎么处理CSS呢?

我们知道,由于原生CSS存在一些问题,比如:

  • 复用时容易样式冲突
  • 没有作用域、没有模块化
  • 没有编程能力

社区涌现出很多解决方案,比如:

  • 命名规范(比如BEM规范)
  • 模块规范(CSS Modules)
  • CSS预处理器(比如Less)
  • CSS In JS
  • CSS框架(Tailwind CSS)
  • ......
[[417026]]

如果我们按以下三个维度评判这些方案:

  • 上手难度:与原生CSS越接近,越好上手
  • 灵活性:拥有越强编程能力,越灵活
  • 能力:能解决多少原生CSS的问题

会发现每个方案都有自己的优势与短板。

图片

比如:

  • CSS In JS方案用JS写CSS,拥有极高灵活性,但加大了上手难度
  • Less(CSS预处理器)可以看作CSS的超集,上手难度低、有一定编程能力,但是CSS自身的问题他也存在

业界常见做法是:同时使用BEM规范(解决命名冲突问题)+ CSS预处理器。

进击的Vue CSS解决方案

我们用这三个维度分析下Vue的SFC(Single-File-Component,单文件组件):

  1. <template> 
  2.   <p>xxx</p> 
  3. </template> 
  4.  
  5. <script> 
  6.   // ... 
  7. </script> 
  8.  
  9. <style scoped> 
  10.   p { 
  11.     color: #0f0; 
  12.   } 
  13. </style> 
  • 上手难度:样式在<style>标签内书写,与原生CSS别无二致,上手简单,符合直觉
  • 能力:scoped标识提供了「模块化」能力
  • 灵活性:可以使用各种预处理器,有一定灵活性

可以看到,Vue SFC采用的是一种各方面没有明显短板,局部很突出(上手难度低)的CSS方案。

随着Vue3.2发布,Vue SFC中的CSS属性获得了「响应式更新能力」,使其灵活性大大提升。

响应式CSS属性

对于如下Vue SFC:

  1. <template> 
  2.   <div class="text">hello</div> 
  3. </template> 
  4.  
  5. <script> 
  6. export default { 
  7.   data() { 
  8.     return { 
  9.       color: 'red' 
  10.     } 
  11.   } 
  12. </script> 
  13.  
  14. <style> 
  15. .text { 
  16.   color: v-bind(color); 
  17. </style> 

<script>标签内定义了状态color = 'red'

.text使用v-bind为color属性绑定该状态。效果如下:

为了验证响应式更新能力, 为div增加点击事件:

  1. <div class="text" @click="color= color === 'red' ? 'green' : 'red'">hello</div> 

点击后会让color状态在red与green间切换。可以看到,页面样式也会同步变化:

Demo地址[1]

不仅是color,你可以为任何CSS属性绑定状态。

那么这个特性是如何实现的呢?

实现原理每个使用v-bind绑定到CSS属性的状态对应一个CSS变量,该CSS变量会作为style属性赋值给组件最外层DOM。

在我们的例子中:

  1. .text { 
  2.   color: v-bind(color); 

其中v-bind(color)会成为CSS变量:

并作为style属性赋值给div:

.text经过编译会使用该CSS变量:

  1. .text { 
  2.   // 编译前 
  3.   /* color: v-bind(color); */ 
  4.   // 编译后 
  5.   color: var(--469af010-color); 

当颜色变化后,CSS变量的值随之变化:

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

Vue3放弃IE这可是说到做到的。

总结

Vue官方称该特性为State-Driven Dynamic CSS[2]

经过这波操作,Vue SFC的CSS灵活性有了很大提高。

并且,有了v-bind这个开头,相信未来会出现更多与「响应式更新」挂钩的「自定义CSS指令」。

之前的自定义指令都是运行时的,以后的指令可能会是基于AST的编译时了。这种转变,你接受吗?

参考资料

[1]Demo地址:

https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHRlbXBsYXRlPlxuICA8ZGl2IGNsYXNzPVwidGV4dFwiIEBjbGljaz1cImNvbG9yPSBjb2xvciA9PT0gJ3JlZCcgPyAnZ3JlZW4nIDogJ3JlZCdcIj5oZWxsbzwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6ICdyZWQnXG4gICAgfVxuICB9XG59XG48L3NjcmlwdD5cblxuPHN0eWxlPlxuLnRleHQge1xuICBjb2xvcjogdi1iaW5kKGNvbG9yKTtcbn1cbjwvc3R5bGU+In0=

[2]State-Driven Dynamic CSS:

https://v3.vuejs.org/api/sfc-style.html#state-driven-dynamic-css

 

责任编辑:姜华 来源: 魔术师卡颂
相关推荐

2021-09-07 10:29:11

JavaScript模块CSS

2023-11-20 08:32:50

HTTP协议

2011-10-27 09:42:19

ASP.NET

2021-04-12 10:20:20

Java微服务Go

2023-11-01 08:36:07

CSSTailwind

2023-04-05 14:19:07

FlinkRedisNoSQL

2020-11-17 15:31:23

Java微服务Go

2022-12-13 07:41:43

CSSCSS Houdi

2013-12-31 09:19:23

Python调试

2022-12-21 15:56:23

代码文档工具

2023-05-23 13:59:41

RustPython程序

2013-12-17 09:02:03

Python调试

2021-05-20 08:37:32

multiprocesPython线程

2013-08-22 10:17:51

Google大数据业务价值

2015-03-16 12:50:44

2011-01-18 10:45:16

乔布斯

2015-02-05 13:27:02

移动开发模块SDK

2012-06-08 13:47:32

Wndows 8Vista

2023-08-02 13:55:22

AI研究

2021-12-14 19:40:07

Node路由Vue
点赞
收藏

51CTO技术栈公众号