中使用js修改变量值_谈一谈css-in-js在React项目中的使用
一、什么是css-in-js
參考:【css in js 簡介】簡單來說,傳統的前端方案推崇"關注點分離"原則,HTML、CSS、JavaScript 應該各司其職,進行分離。
而在react項目中,更提倡組件化方案,自然形成了將HTML、CSS、JavaScript集中編寫管理的方式。
開發方式由"關注點分離"變為了"關注點混合",成為了我們在react中所熟悉的寫法:
const Widget = () => {<div style={{color: 'white',fontSize: '12px'}} onClick={() => doSometing()}>text </div> }但是這種寫法的弊端在于,react中的style僅僅是簡單的Object,不支持復雜的嵌套、選擇器等特性,使用起來很不方便。 因此,便出現了大量的三方庫來進行拓展,這些庫統稱為css-in-js。它們一般都支持樣式嵌套、選擇器、主題配置等特性。
有人專門統計了現有的css-in-js三方庫,輪子不要太多: css in js 三方庫一覽 。比較流行的主要有: styled-components, emotion, glamorous。盡管css-in-js帶來許多好處,但仍有不足,在某些場景下使用仍然較繁瑣。比如繁瑣的將css屬性映射到props中的操作、使用theme時需要寫很長的解析表達式(props => props.theme.colors.primary)等等。
因此,除了這些css-in-js庫之外,還有人基于它們做了更進一步的封裝,提供了一些標準api來方便我們更快速的使用css-in-js特性,比如:rebass,theme-ui。
二、css-in-js 的使用
基于emotion舉例
emotion的用法示例
emotion 官方文檔
emotion 同時支持 css props寫法和styled寫法
1.string + css props 寫法
import { css, jsx } from '@emotion/core'const color = 'white'render(<divcss={css`padding: 32px;background-color: hotpink;font-size: 24px;border-radius: 4px;&:hover {background-color: ${color};}`}>Hover to change color.</div> )2.object + css props寫法
import { css, jsx } from '@emotion/core'const color = 'white'render(<divcss={{padding: '32px',backgroundColor: 'hotpink',fontSize: '24px',borderRadius: '4px','&:hover': {backgroundColor: color}}}>Hover to change color.</div> )3.string + styled 寫法
import styled from '@emotion/styled'const color = 'white'const Button = styled.div`padding: 32px;background-color: hotpink;font-size: 24px;border-radius: 4px;&:hover {background-color: ${color};} `render(<Button>This my button component.</Button>)4.object + styled 寫法
import styled from '@emotion/styled'const color = 'white'const Button = styled.div({padding: '32px',backgroundColor: 'hotpink',fontSize: '24px',borderRadius: '4px','&:hover': {backgroundColor: color}} )render(<Button>This my button component.</Button>)可以看到,
- string寫法是純粹的css樣式,而object寫法類似于react的style object,但是支持嵌套和selector。
- css props寫法可以直接將樣式寫在組建中,而styled寫法是先將組件封裝成一個新的組件后再使用。
更多特性,請查看官方文檔,此文不再贅述。
emotion 與 styled-components 如何選擇
除了emotion之外,styled-components也比較常用
styled-components 官方文檔
在使用上,styled-components 與 emotion 的styled寫法一樣,需要將組件封裝成一個新的組件后再使用。
鑒于emotion已經支持了styled模式,可以優先選擇emotion。
也可以參考theme-ui項目選擇emotion的原因:
While there are many different solutions to handling CSS in JavaScript, Styled Components and Emotion have become the most widely-used industry-standard libraries. If you're building a custom component library, either Styled Components or Emotion should suit your needs just fine.
For Theme UI, the decision was primarily based on these factors:
- Emotion's implementation of the css prop and the custom JSX pragma allows for better integration with @styled-system/css
- The Emotion API includes more lower-level utilities, like createEmotion that could be leveraged when considering how multiple themes could be composed together
- Emotion's theming context is directly available in @emotion/core, allowing this library to leverage React's context API in different ways
- In the case of Theme UI internals, the styled higher-order component utility is not necessarily the best API for creating components, and by not including @emotion/styled in the core package the bundle size is kept to a minimum – i.e. most of the same things can be achieved with the css prop
三、Rebass:更進一步&開箱即用
rebass帶來了什么
Rebass是基于styled-system、emotion、styled-components構建的一個可定制組件庫。基于Rebass可以快速的構建符合項目風格的基礎組件。
不同于antd這類UI庫,Rebass只提供幾個原始的組件(Box、Flex、Text、Heading、Button、Link、Image、Card),這些組件都非常的初級,就像div一樣。基于這些組件,以及Rebass的主題特性,我們很容易就可以定制出項目用到的組件。
Rebass支持多種方式來編寫組件樣式: - sx props:基于reflexbox實現,類似于emotion中的object css prop,并且能夠直接使用theme中定義的主題屬性 - style prop:基于styled-system實現 - css prop:繼承emotion的用法 - styled:繼承emotion的用法
幾種用法舉例:
// theme.js export default {colors: {primary: 'red'},variants: {badge: {display: 'inline-block',p: 1,color: 'white',bg: 'primary',borderRadius: 2,}}, } // 1.sx prop <Box variants="badge" sx={{bg: 'primary',height: '100px' }}><Text>123</Text> </Box>// 2.style prop <Box variants="badge" bg='primary' height='100px'><Text>123</Text> </Box>從例子中可以看到: - 在rebass組件中我們可以直接通過theme的key來使用主題樣式,而不用寫諸如props => props.theme.colors.primary之類的繁瑣語句。 - 我們可以把css屬性當做普通的prop傳入組件(height),而不用做任何額外的操作。 - 我們可以通過variants來包裹一組css樣式,使得主題具備了類似class的功能。這個是非常有用的一個功能,簡化了主題樣式的使用,并提高了可復用性。
rebass是如何做到的
Rebass庫的源碼非常少,主要是整合了reflexbox、styled-system以及styled-components的特性。
reflexbox
reflexbox文檔
reflexbox基于Emotion和Styled Components實現,提供了兩個具有響應式特性的組件:Box和Flex。除此以外,提供了sx prop特性來編寫樣式,遵循主題樣式規范,完美支持主題定制。可以說Rebass的主要特性全部由reflexbox實現,僅僅是在其之上做了一層封裝,定制了幾個基礎組件,并提供了對styled-components的支持。
styled-system
styled-system 官方文檔
Styled System is a collection of utility functions that add style props to your React components and allows you to control styles based on a global theme object with typographic scales, colors, and layout properties.Styled System 提供了一系列工具方法來給React組件添加樣式屬性,并且支持使用全局樣式來控制組件的尺寸、顏色和布局等屬性。
不好理解?可以看一個簡答的例子,我們有一個白色組件,常規寫法如下:
.white-block {color: '#fff' }<Compnent className="white-block"/>通過styled-system包裝后,可以把color作為一個props放入組件中。類似于給html element增加自定義標簽。
// 定義組件 import styled from '@emotion/styled' import { color } from 'styled-system'const Compnent = styled.div`${color} `export default Compnent// 使用組件,這里包裝后不僅提供了color屬性,也提供了bg(background-color)屬性 <Compnent color='#fff' bg='red'/>這就是文檔中提到的:
Styled System is a collection of utility functions that add style props to your React componentsstyled-system 是如何工作的
官方說明鏈接
繼續上面的例子,${color} 里面有什么魔法? 實際上,從styled-system導入的color是一個類似于這樣的函數
props => `color: ${props.color}; background-color: ${props.bg}`正如描述中所說,styled-system就是幫我們把css歸類,并包裝成了一些可以在emotion或者styled-components這類css-in-js庫中使用的工具方法,方便我們使用。
四、結語
除了文章中介紹的內容外,css-in-js還支持許多好用的特性,比如響應式布局、選擇器、動畫等等。
如果想體驗css-in-js,可以先試試Emotion,了解一些基本的原理,然后直接上Rebass吧,用起來還是挺香的。
歡迎留言交流~
關于我們
深圳市淺海科技有限公司
我們是一個高效、熱情、有責任的技術團隊,承接各種軟件系統定制需求。
長期招聘遠程開發者,如果您喜歡嘗試新技術,有一點代碼潔癖,能夠使用文檔進行高效的溝通,React/nodejs/ES6任意一種玩的飛起,那么,歡迎來撩~(想賺快錢的請繞道,謝謝)
簡歷請發送到:service@qianhaikeji.cn當然,也歡迎甲方爸爸把項目甩我們臉上。
總結
以上是生活随笔為你收集整理的中使用js修改变量值_谈一谈css-in-js在React项目中的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android涂鸦板保存功能,andro
- 下一篇: xshell 软件的窗口一直是置顶 调整