由於組件可以在不同的context中使用,有幾種方法可以解決這個問題,官方連結。
你可能需要為特定實現更改組件的樣式,為此可以使用以下解決方案:
每個組件都提供一個 className 屬性,該屬性始終應用於根元素。
範例使用 withStyles() 將自定義樣式註入 DOM,並通過其 classes 屬性將類名傳遞給 ClassNames 組件。這裡可以選擇任何其他解決方案。
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import Button from '@material-ui/core/Button';
import { withStyles } from '@material-ui/core/styles';
const styles = {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
},
};
function ClassNames(props) {
const { classes, children, className, ...other } = props;
return (
<Button className={clsx(classes.root, className)} {...other}>
{children || 'class names'}
</Button>
);
}
ClassNames.propTypes = {
children: PropTypes.node,
classes: PropTypes.object.isRequired,
className: PropTypes.string,
};
export default withStyles(styles)(ClassNames);
關於Clsx,他可以減少我們用三元運算的方式撰寫 className。
本來的寫法:
// in return
<div
className={`
MuiButton-root
${disabled ? 'Mui-disabled' : ''}
${selected ? 'Mui-selected' : ''}
`}
/>
引入之後:
<div
className={clsx('MuiButton-root', {
'Mui-disabled': disabled,
'Mui-selected': selected,
})}
/>
當 className 屬性不夠用時,並且需要訪問更深層次的元素,可以利用 classes 對象屬性來自定義 Material-UI 為給定組件注入的所有 CSS。
每個組件的classes列表記錄在組件 API 頁面中,可以透過瀏覽官方文件的 component API 或者直接透過 dev tools 查看,這個例子也使用了 withStyles()(如上文),但在這裡,ClassesNesting 使用 Button 的 classes 屬性來提供一個對象,該對象將要覆蓋的 classes 名稱(樣式規則)映射到要應用的 CSS class names(值)。組件的現有classes將繼續注入,因此只需提供想要添加或覆蓋的特定樣式。
請注意,除了按鈕樣式之外,按鈕標籤的大小寫也已更改:
const useStyles = makeStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
},
label: {
textTransform: 'capitalize',
},
});
// ...in export function
const classes = useStyles();
// ...in return
<Button
classes={{
root: classes.root, // class name, e.g. `classes-nesting-root-x`
label: classes.label, // class name, e.g. `classes-nesting-label-x`
}}
>
classes nesting
</Button>
參考連結。
瀏覽器開發工具可以節省大量時間。
Material-UI 的class names 遵循模式:
Mui[component name]-[style rule name]-[UUID]
使用開發工具,你知道你需要定位 Button 組件和標籤樣式規則
<Button classes={{ label: 'my-class-name' }} />
上面的範例可以通過使用與子組件相同的 CSS API 來壓縮。在這個例子中,withStyles() HOC 正在注入一個由 Button 組件使用的 classes 屬性。
const StyledButton = withStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
},
label: {
textTransform: 'capitalize',
},
})(Button);
// in retutn
<StyledButton>classes shorthand</StyledButton>
組件的特殊狀態,例如 hover, focus, disabled 或 selected,特異性是應用於給定 CSS 聲明的權重。
為了覆蓋組件的特殊狀態,你需要增加特異性。
.Button {
color: black;
}
.Button:disabled { /* Increase the specificity */
color: white;
}
// in return
<Button disabled className="Button">
有時後不能使用偽類,因為平台中不存在狀態。以MenuItem 組件和選中狀態為例,除了訪問嵌套元素外,classes 屬性還可用於自定義 Material-UI 組件的特殊狀態:
.MenuItem {
color: black;
}
.MenuItem.selected { /* Increase the specificity */
color: blue;
}
// in return
<MenuItem selected classes={{ root: 'MenuItem', selected: 'selected' }}>
jss-nested 插件可以使增加特異性的過程更容易。
const styles = {
root: {
'&$disabled': {
color: 'white',
},
},
disabled: {},
};
需要將生成的兩個類名(root 和 disabled)應用於 DOM 以使其工作。
// in return
<Button
disabled
classes={{
root: classes.root, // class name, e.g. `root-x`
disabled: classes.disabled, // class name, e.g. `disabled-x`
}}
>
classes state
</Button>
以上就是今天的全部內容了,明天會接續 2~5 的方法講解。