styled-component
功能說明
它具有以下的特色
- 支援巢狀架構、偽元素寫法
- 相似於 react component ,同樣能使用
props
- 產生的元件可以彼此繼承
- 自動添加瀏覽器前綴:簡化兼容處理
- 支援 SSR 渲染,需搭配工具(例如:Babel)
基本使用
添加靜態 css 樣式
假設我們需要一個黃底黑字的 <button>
import styled from "styled-components";
const yellowButton = styled.button`
background:yellow;
color:black;
`
元件加入 props
根據 props 值決定樣式
//代表這個樣式會根據 props 的值進行設定
cssName: ${props=>props.name}
//ex: 顏色設定
color:${props=>props.color}
以 props 作為條件,決定要加入什麼樣式
//如果沒有 props 則預設顏色為黑色
color:${props=>props.color? props.color:'black'}
樣式繼承功能
這個功能用來實現在某個元件基礎上,延展、客製化新的元件。
//基礎元件
const YellowText = styled.p`
color:yellow;
`
//今天想要產生文字為黃色,再加上 font-weight
const YellowWeightText = styled(YellowText)`
font-weight:700
`
attrs 添加靜態屬性
像是 <input />
,<button>
這類的元素,就會有屬性可以設定,例如 type
placeholder
checked
等。
import styled from "styled-components";
let yellowButton = styled.input.attrs({
type:`password`,
// 加入自定義的屬性
foo: 'custom'
})`
background:yellow;
color:black;
`
效能考量
注意 styled 元件撰寫位置
基於效能考量,文件通常建議將 styled 產生的元件,定義於渲染元件之外,避免每次重新渲染都會重新創造元件。
import styled from 'styled-component'
//不會重複執行元件創建
const StyledDiv = styled.div`
color:red;
`
const WrapperPage = ({props})=>{
//每次渲染都會重複創建
const StyledP = styled.p`
color:black;
`
return
<>
<StyledDiv>
<StyledP></StyledP>
<StyledDiv>
</>
}
搭配 Babel
1. 更具可讀性的類名 2. 伺服器端渲染 (SSR) 支持 3. 去除未使用的樣式( 更小的打包體積)
情境題
解決 css 編譯後亂碼問題
將 css 直接定義在 styled-component 內 經過編譯後,會以亂碼方式顯示在網頁上,造成後續維運不便,解決方法:改在元件內部定義 className
import styled from "styled-components";
const StyledSample = styled.div`
.test{
display:flex;
}
實際運用 - 專案架構設計
src/
└── styles/
├── base/
│ ├── BaseButton.js
│ ├── BaseContainer.js
│ ├── BaseInput.js
│ └── index.js
├── theme/
│ ├── theme.js
│ └── GlobalStyle.js
├── utils/
│ ├── flexCenter.js
│ ├── typography.js
│ └── index.js
└── index.js
base/資料夾
用來存放基礎樣式元件(Base Components),主要是封裝 HTML 元素,提供基本樣式設定,這些元件沒有特定的業務邏輯,可以在多處重複使用。
theme/資料夾
可以用來存放全域顏色、間距(margin,padding),以我的專案作法是會統一定義於 theme.js
(如下圖)
//theme.js
export const theme = {
colors: {
primary: '#007BFF',
secondary: '#6C757D',
background: '#F8F9FA',
text: '#212529',
},
spacing: {
small: '8px',
medium: '16px',
large: '24px',
},
borderRadius: '4px',
};
透過 ThemeProvider
提供的 Context API 將內容給所有子元件
import {theme} from "/theme.js"
//將定義內容傳入
<ThemeProvider theme={theme}>
//...
</ThemeProvider>
utils/資料夾
通常用來存放工具樣式,例如常用的排 版方式、對齊方式、字體樣式,例如你可以將 flex
置中的排版組裝為一個元件,輸出重複使用。
// flexCenter.js
import { css } from 'styled-components';
export const flexCenter = css`
display: flex;
align-items: center;
justify-content: center;
`;
下面是引入元件使用的情境
// 在组件中使用
import styled from 'styled-components';
import { flexCenter, heading1 } from './styles/utils';
const Card = styled.div`
${flexCenter};
flex-direction: column;
background-color: ${({ theme }) => theme.colors.background};
padding: ${({ theme }) => theme.spacing.medium};
`;
const Title = styled.h1`
${heading1};
margin-bottom: ${({ theme }) => theme.spacing.small};
`;