最近須要作一個表格組件,組件需求:css
最終採用grid實現需求。實現的時候遇到一個問題,若是css和js分開寫,css只能是定值,沒有靈活性。因此考慮採用css in js
的形式。關於css in js
相關的概念介紹能夠參考阮一峯老師的文章:css in js 介紹。html
在github上找了一下關於這方面的組件,發現styled components 很是不錯,簡單易上手,git
npm下載:`npm i styled-components -S`
注意:github
React < 16 須要下載3.x.x版本的
根據文檔先寫一個簡單的demo。npm
能夠看到,它的實現方式並非傳統的以對象的形式寫樣式,而是將須要添加樣式的元素加到styled對象上,而後跟一個(``)反引號標籤,在裏面以正常的css格式寫樣式。而後返回一個組件,把組件替換原來的div便可。this
實現效果:spa
html代碼:code
css代碼:component
剛纔咱們添加樣式的元素是html元素,那麼給組件添加樣式能夠麼?實踐一下:htm
const H1 = ({ className }) => <h3 className={className}>我是App</h3>; const HH = styled.H1` font-size: 30px; color: red; `;
運行,報錯:
咋回事?原來styled不支持以 . 符號的形式爲組件添加樣式,須要以參數形式傳遞,修改上面代碼
const HH = styled(H1)` font-size: 30px; color: red; `;
將H1
組件以參數形式傳遞給styled,就能夠了。
想給元素添加僞元素樣式,子元素樣式能夠麼?沒問題,styled components
支持樣式嵌套,按照相似Less或Scss的書寫方式就能夠了。
const Container = styled.div` width: 300px; max-width: 500px; min-width: 200px; transition: all 1s ease-in-out; background-color: rgba(240, 240, 240, 0.9); ::after { content: 'after'; display: table; color: blue; } span { color: green; } `;
以上咱們寫的組件都是在Class外面,那咱們要根據props設定樣式怎麼辦?styled components
一樣支持在Class內生成組件,並接受props傳遞過來的值,這個props並非咱們的Class接收的props,它是添加樣式的元素上的Props,意思就是
class Demo { render(){ return <Styled name="guoshi"></Styled> } } Demo.defaultProps = { age: 18 } const Styled = styled.p` color: ${props=>{console.log(props)}} // {name: "guoshi",theme:{...}} `
若是想使用Class的props怎麼辦?看代碼:
generateStyle = () => { const {row, col, justify, data, prefixCls, showborder = true, rowgap = 0, colgap = 0} = this.props; const child = []; data.map((item,index)=> (item.colSpan || item.rowSpan) ? child.push({index:index+1,colSpan:item.colSpan, rowSpan:item.rowSpan}):null); const bordernone = []; for(let i = 0; i < row; i++) { bordernone.push(1 + i*col); } const UlContainer = styled.ul.attrs({className: prefixCls})` display: grid; grid-template-columns: ${()=> { let arr = []; arr.length = col; return arr.fill('1fr').join(' '); }}; grid-template-rows: ${()=> { let arr = []; arr.length = row; return arr.fill('1fr').join(' '); }}; grid-gap: ${rowgap} ${colgap} ; justify-items: ${()=> justify || "center"}; ::before { display: none; } li { width: 100% !important; } ${ child.map(({index, colSpan, rowSpan}) =>` li:nth-child(${index}) { grid-column-start: ${index%col === 0 ? index : index%col}; grid-column-end: ${colSpan ? (colSpan+(index%col === 0 ? index : index%col)) : ((index%col === 0 ? index : index%col)+1)} grid-row-start: ${Math.ceil(index/col)}; grid-row-end: ${rowSpan ? rowSpan+Math.ceil(index/col) : Math.ceil(index/col)+1}; align-items: start; } `).join(' ') } li + li { border-left: 1px dashed rgba(0,0,0,0.3); } ${ bordernone.map(bordernoneindex=>` li:nth-child(${bordernoneindex}) { border-left: none; } `).join(' ') } `; return UlContainer; }
提早把最後代碼放出來了,styled.ul.attrs({})
就是爲元素添加額外的屬性,好比className、placeholder等,從代碼中能夠看到,不管是Class的props仍是元素自身傳進來的props,styled均可以接收,你能夠自定義任何你想實現的規則,更方便咱們配置的靈活性。
其實到這裏,使用上沒有任何問題了,關於keyframes等規則官網上都有demo,也很是容易實現。想嘗試的小夥伴如今就能夠碼一遍。不過本章遺留了不少問題:
下一章,我會根據styled componnets
源碼解答上述問題。
最後,祝生活愉快。