material ui是一个支持PC端、移动端的UI框架,使用的过程中也踩了很多坑,下面针对如何使用以及注意事项简要总结一下(当前使用版本为最新版1.0)
1. 使用字体图标
在index.html下添加如下内容,即可使用字体图标
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
具体使用,里面直接填写图标的名字,图标名字地址见 Material icons
<i className="material-icons">account_circle</i>
//导入Icon组件
import Icon from 'material-ui/Icon';
<Icon>star</Icon>
- 配置主题,全局进行共享 具体见 配置主题
/*配置主题样式*/
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
const theme = createMuiTheme({
//可以配置颜色,间距等等
palette: {
primary: { main: '#88c33b' }
},
});
//根组件
<MuiThemeProvider theme={theme}>
<BrowserRouter>
<App>
<Routes></Routes>
</App>
</BrowserRouter>
</MuiThemeProvider>
- 子组件通过withStyles可以获取主题信息,material-ui 1.x版本中,对material提供的组件进行样式修改进行了提取,通过组件对外暴露的接口来对组件样式进行修改,有时候直接为组件添加className也可以达到效果,但是当要修改组件内部组件的时候,组件对外暴露的接口就起到了作用.
其中样式使用了CSS in JS 方案
import React from 'react';
import { withStyles } from 'material-ui/styles';
import { CircularProgress } from 'material-ui/Progress';
// 所有的样式都在styles里面进行配置,这个theme就是我们上面所配置的主题
const styles = theme => ({
progress: {
margin: theme.spacing.unit * 2,
},
wrap: {
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 1000,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: 'rgba(0, 0, 0, 0.5)',
}
});
// 这里使用es7的装饰器,需要通过babel编译,这种方式更简洁,当然也可以使用withStyles(styles)(Loading)这种方式
@withStyles(styles)
class Loading extends React.Component {
render() {
const {classes} = this.props;
return (
<div className={classes.wrap} style={{display: 'flex'}}>
<CircularProgress className={classes.progress} size={50} />
</div>
)
}
}
export default Loading;
使用withStyles这种方式会返回一个高阶组件,高阶组件会将提供的样式就是styles通过属性classes添加到内部组件的props上,这样可以在内部组件通过this.props.classes来添加styles中的样式
注意:withStyles所返回的高阶组件如果需要保持对内部Loading组件的引用,则需要通过为高阶组件添加innerRef={(loading) => {this.loading = loading}}的方式来进行访问,如果只是通过ref则拿到是高阶组件,而不是内部的loading组件
如果我们需要把样式单独抽离出来放到独立的css文件中去,然后在组件中进行样式文件的引用,会发现,我们写的样式被组件默认提供的样式给覆盖了,这是以为material ui 将组件自身的样式设为了除!important外的最高优先级.也就是组件自身携带的样式在index.html中的位置永远是head中的最下方.
因此如果需要对样式进行抽离的话需要改变material ui中对样式的注入方式,将我们抽离的样式放在最下方
import React, {Component} from 'react';
import JssProvider from 'react-jss/lib/JssProvider';
import { create } from 'jss';
import { createGenerateClassName, jssPreset } from 'material-ui/styles';
import DevTools from 'mobx-react-devtools'
import './App.css';
const generateClassName = createGenerateClassName({
//开发模式与生产模式样式名称固定,我们自己添加的样式类会以jss-为前缀,当然也可以在下面进行修改
dangerouslyUseGlobalCSS: true
});
const jss = create(jssPreset());
// We define a custom insertion point that JSS will look for injecting the styles in the DOM.定义一个插入点,最好不要使用注释的方式,因为如果是注释,在打包的时候会被打包插件给移除掉
// 在index.html中添加一个id为jss-insertion-point'的元素,表示要注入的位置
jss.options.insertionPoint = document.getElementById('jss-insertion-point');
class App extends Component {
render() {
return (
<JssProvider jss={jss} generateClassName={generateClassName}>
<div className="App">
{
this.props.children
}
<DevTools/>
</div>
</JssProvider>
);
}
}
export default App;
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<noscript id="jss-insertion-point"></noscript>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<style>
#root {
width: 100%;
height: 100%;
}
</style>
<title>React App</title>
</head>