介紹:css
styled-components 樣式化組件,主要做用是它能夠編寫實際的CSS代碼來設計組件樣式,也不須要組件和樣式之間的映射,即建立後就是一個正常的React 組件,而且能夠附加樣式給當前組件。下面經過兩種平臺的樣式書寫來比較說明:html
a.react-native 下寫樣式的方式:react
var styles = StyleSheet.create({ container: { borderRadius: 4, borderWidth: 0.5, borderColor: '#d6d7da', }, title: { fontSize: 19, fontWeight: 'bold', }, activeTitle: { color: 'red', }, }); <View style={styles.container}> <Text style={[styles.title, this.props.isActive && styles.activeTitle]} /> </View>
經過 StyleSheet 庫建立一個樣式表,再到元素標籤上引用建立的樣式 styles.containercss3
b.Html + Css的寫法:react-native
<style type="text/css"> .container{ borderRadius: '5px', borderWidth: '5px', borderColor: '#d6d7da', } .title{ fontSize: '19px', fontWeight: 'bold', } .activeTitle{ color: 'red', } </style> <div class="container"><span class="title"></span></div>
根據上面兩種例子能夠看出當元素須要某類樣式時,都須要與之對應,纔能有具體的顯示效果。瀏覽器
接下來看 styled-components 樣式化組件是如何作到組件與樣式之間不須要映射的antd
如:建立一個 <h1>標籤 的樣式化組件,在React中直接使用建立好的Title組件就能夠了ide
//在h1後添加附加的樣式
const Title = styled.h1` font-size: 1.5em; text-align: center; color: palevioletred; `;
render( <Title> Hello styled-component </Title> );
那麼問題來了,經過styled-component建立的樣式化組件在頁面上最終渲染成什麼呢了?函數
先看效果:優化
再看頁面代碼:實際上就是經過 <h1>元素標籤渲染的
幾種經常使用的樣式化組件方法
# injectGlobal # 編寫全局CSS的輔助方法。它不返回組件,而是直接將樣式添加到樣式表中
這個跟咱們平時在寫html頁面,會先把一些須要重置瀏覽器的樣式加到頁面上的作法相似,主要做用是:重置樣式及書寫全局可共用的樣式
import { injectGlobal } from 'styled-components'; injectGlobal` @font-face { font-family: 'Operator Mono'; src: url('../fonts/Operator-Mono.ttf'); } body { margin: 0; } `;
# StyledComponent # 樣式化組件聲明方式:styled.tagname、styled(Component) 兩種方式
第一種直接經過styled點一個元素標籤,將button元素轉化成樣式化組件
第二種是重寫樣式化組件的部分樣式,好比TomatoButton
還有一種是將一個非樣式化組件轉換成樣式化組件並附加樣式,如使用的螞蟻金服的UI:Flex
import styled from 'styled-components';
import { Flex, List} from 'antd-mobile';
const Button = styled.button` background: palevioletred; border-radius: 3px; border: none; color: white; `; const TomatoButton = styled(Button)` background: tomato; `;
const MoneyDetail = styled(Flex).attrs({
direction: 'row',
justify: 'between',
})`
padding: 0.26rem;
`
另外介紹兩種方法
.extend:建立一個新的StyledComponent而且繼承它的規則
如:TomatoButton繼承了Button的樣式規則,並使用一些與顏色相關的樣式進行擴展(其實就是覆蓋了被繼承組件的某些樣式)。
const TomatoButton = Button.extend` color: tomato; border-color: tomato; `;
如:用<a>標籤替換<button>標籤,但仍是使用相同的樣式,至關於<button>有的樣式<a>標籤同樣都有
const Link = Button.withComponent('a')
# Supported CSS # 樣式化組件它支持全部的CSS及嵌套,如僞元素使用、選擇器使用、媒體查詢、css及css3的各種聲明樣式
const Example = styled.div` padding: 2em 1em; background: papayawhip; /* 僞元素使用:當鼠標懸浮在div塊上時顯示背景色palevioletred */ &:hover { background: palevioletred; } /* 媒體查詢:在屏幕小余600px的寬度下顯示如下樣式 */ @media (max-width: 600px) { background: tomato; &:hover { background: yellow; } } /*css選擇器使用:給當前div元素下的子元素p添加下劃線的樣式*/ > p { text-decoration: underline; } `; render( <Example> <p>Hello World!</p> </Example> );
# Attaching additional props # 附加額外的 props,可使用.attrs構造函數,將props(或「attributes」)附加到當前組件
好比:聲明一個input輸入框,用html方式寫就是:<input type="text" length="20" padding="10px"/>
而經過樣式化組件聲明input輸入框就能夠按下面的寫法:
import styled from 'styled-components'; const Input = styled.input.attrs({ type: 'text', length: props => props.length || 10 })` background: palevioletred; border-radius: 3px; border: none; color: white; padding: ${props => props.padding} `;
<Input length="20" padding="10px">
實際上 attrs 方法就是一種添加屬性的方式,也能夠接收組件傳過來的prop,如上面<Input>組件傳的padding、length屬性。
.attrs對象還能夠接收函數:好比咱們聲明一個按鈕,並給它添加一個點擊事件
const Button = styled.button.attrs({ onClick: props => props.onClick || null })` background-color: '#e1e1e1'; color: ${props => props.color || '#FFFFFF'}; width: ${props => props.width || '1.92rem'}; height: ${props => props.height || '0.64rem'}; font-size: ${props => props.fontSize || '0.24rem'}; border-radius: ${props => props.borderRadius || '0.02rem'}; padding: 0.08rem 0.12rem 0.08rem 0.12rem; ${props => props.style || ''} `
<Button onClick={() => {alert('點擊我啊!')}}>
另外列舉一個經過prop傳遞值優化樣式的方式
精靈圖片經過傳遞的prop值裁剪相應圖片:
聲明一個 <i>元素的樣式化組件,並附一張背景圖片,引用時分別給定不一樣圖片的裁剪位置,如:
position={{backgroundPosition:'center -0.52rem'}},在樣式聲明中經過 ${props => props.position} 獲取當前須要裁剪顯示的位置
const WayImage = styled.i` background-image:url('${require('./resources/provided.png')}'); background-size: 0.38rem 2.1rem; background-repeat: no-repeat; ${props => props.position}; width: 0.4rem; height: 0.42rem; display: inline-block; vertical-align: middle; ` <WayImage position={{backgroundPosition:'center -0.52rem'}}/> <WayImage position={{backgroundPosition:'center -1.1rem'}}/>