CSS也能像組件狀態同樣響應式更新?

你們好,我是卡頌。javascript

不知道平時在項目裏你怎麼處理CSS呢?css

咱們知道,因爲原生CSS存在一些問題,好比:html

  • 複用時容易樣式衝突vue

  • 沒有做用域、沒有模塊化java

  • 沒有編程能力編程

社區涌現出不少解決方案,好比:api

  • 命名規範(好比BEM規範)瀏覽器

  • 模塊規範(CSS Modules)markdown

  • 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的編譯時了。這種轉變,你接受嗎?

相關文章
相關標籤/搜索