styled-components 背後的魔法

styled-components 定義組件的風格爲git

1 const Button = styled.button`
2   background-color: papayawhip;
3   border-radius: 3px;
4   color: palevioletred;
5 `

這個Button變量如今是一個React組件,能夠像其餘React組件同樣渲染!那麼它是若是實現的?數組

模板字符串

事實證實,這個奇怪的 styled.button`` 符號其實是 ES6中引入的一種名爲 Tagged Template Literal(模板字符串) 的新功能。函數

從本質上講, styled.button``styled.button()都是調用一個函數,但當你傳入參數之後,就會發現 咱們不同、不同、不同 !this

那麼讓咱們建立一個簡單的函數來看看哪裏不同:spa

1 const logArgs = (...args) => console.log(...args)

您能夠在控制檯中執行代碼查看結果code

1 logArgs('a', 'b')
2 // -> a b
3 
4 logArgs``
5 // -> [""]
6 
7 logArgs`I like pizza`
8 // -> ["I like pizza"]

顯而易見,正常調用輸出的是一個字符串,而以模板字符串的方式調用輸出的是一個數組。component

那當咱們傳入字符串插值之後會發生什麼呢?blog

1 const favoriteFood = 'pizza'
2 
3 logArgs(`I like ${favoriteFood}.`)
4 // -> I like pizza.
5 
6 
7 logArgs`I like ${favoriteFood}.`
8 // -> ["I like ", "."] "pizza"

 Amazing,咱們獲得了一個數組和一個字符串,第一個參數是被插值分割而生成的數組,第二個參數就是插值ip

 

那當咱們傳入函數時,又會怎樣?字符串

1 logArgs(`Test ${() => console.log('test')}`)
2 // -> Test () => console.log('test')
3 
4 logArgs`Test ${() => console.log('test')}`
5 // -> ["Test", ""] () => console.log('test')

你應該猜到了第二行輸出的是一個字符串,第五行是一個數組和一個真正的函數。

咱們來驗證一下

 1 const execFuncArgs = (...args) => args.forEach(arg => {
 2   if (typeof arg === 'function') {
 3     arg()
 4   }
 5 })
 6 
 7 execFuncArgs('a', 'b')
 8 // -> undefined
 9 
10 execFuncArgs(() => { console.log('this is a function') })
11 // -> "this is a function"
12 
13 execFuncArgs('a', () => { console.log('another one') })
14 // -> "another one"
15 
16 
17 execFuncArgs(`Hi, ${() => { console.log('Executed!') }}`)
18 // -> undefined
19 
20 execFuncArgs`Hi, ${() => { console.log('Executed!') }}`
21 // -> "Executed!"

應用場景

以 Button 大小爲例

1 const Button = styled.button`
2   font-size: ${props => props.primary ? '2em' : '1em'};
3 `
4 
5 // font-size: 2em;
6 <Button primary />
7 
8 // font-size: 1em;
9 <Button />

 

 

Refers

相關文章
相關標籤/搜索