乐趣区

关于前端:CSS也能像组件状态一样响应式更新

大家好,我是卡颂。

不晓得平时在我的项目里你怎么解决 CSS 呢?

咱们晓得,因为原生 CSS 存在一些问题,比方:

  • 复用时容易款式抵触
  • 没有作用域、没有模块化
  • 没有编程能力

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

  • 命名标准(比方 BEM 标准)
  • 模块标准(CSS Modules)
  • CSS预处理器(比方Less
  • CSS In JS
  • CSS框架(Tailwind CSS

……

如果咱们按以下三个维度评判这些计划:

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

会发现每个计划都有本人的劣势与短板。

比方:

  • CSS In JS计划用 JSCSS,领有极高灵活性,但加大了上手难度
  • LessCSS预处理器)能够看作 CSS 的超集,上手难度低、有肯定编程能力,然而 CSS 本身的问题他也存在

业界常见做法是:同时应用 BEM 标准(解决命名抵触问题)+ CSS预处理器。

进击的 Vue CSS 解决方案

咱们用这三个维度剖析下 VueSFC(Single-File-Component,单文件组件):

<template>
  <p>xxx</p>
</template>

<script>
  // ...
</script>

<style scoped>
  p {color: #0f0;}
</style>
  • 上手难度:款式在 <style> 标签内书写,与原生 CSS 别无二致,上手简略,合乎直觉
  • 能力:scoped标识提供了 模块化 能力
  • 灵活性:能够应用各种预处理器,有肯定灵活性

能够看到,Vue SFC采纳的是一种各方面没有显著短板,部分很突出(上手难度低)的 CSS 计划。

随着 Vue3.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-bindcolor属性绑定该状态。成果如下:

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

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

点击后会让 color 状态在 redgreen间切换。能够看到,页面款式也会同步变动:

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 SFCCSS 灵活性有了很大进步。

并且,有了 v-bind 这个结尾,置信将来会呈现更多与 响应式更新 挂钩的 自定义 CSS 指令

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

退出移动版