1. 实现Icon
// icon组件的使用
<Icon onClick={() => {
alert('hello icon')
}} name='jiadian-dianfanguo' style={{color:'red'}}/>
// icon组件
import React,{Component} from 'react'
import PropTypes from 'prop-types'
import '../../font-demo/iconfont.css' // 下载的图标库
class Icon extends Component{
static propTypes = {
name: PropTypes.string
}
static defaultProps = {
name: 'aaa'
}
render() {
const {
name,
...rest
} = this.props
return (
<span {...rest} className={`icon iconfont icon-${name}`}></span>
)
}
}
export default Icon
2. 实现Button
// button 组件的使用
<Button onClick={() => {
alert('hello button')
}} type='primary' icon='jiadian-dianfanguo'>提交</Button>
//Button
import React,{Component} from 'react'
import PropTypes from 'prop-types'
import Icon from '../Icon'
import './index.scss'
class Button extends Component{
static propTypes = {
icon: PropTypes.string,
type: PropTypes.string
}
static defaultProps = {
icon: 'dianpu',
type: 'primary'
}
render() {
const {
icon,
children,
type,
...rest
} = this.props
return (
<button {...rest} className={`react-ui__btn--${type}`}>
<Icon name={icon}/>
{children}
</button>
)
}
}
export default Button
3. 实现Input
// Input 组件的使用
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Input from './react-ui/Input/index1'
class App extends React.Component{
constructor(props) {
super(props);
this.state ={
value: 'a'
}
}
value = '1'
render() {
return (
<div>
<Input size='large'/>
<br/>
<Input size='middle' prefix='dianpu'/>
<br/>
<Input size='small'
value={this.state.value}
onChange={(e) => {
this.setState({
value: e.target.value
})
}}
/>
<Input
rule={/\d/}
message="只允许输入数字"
size='small' defalutValue={this.value} onChange={(e) => {
this.value = e.target.value
}}/>
</div>
);
}
}
export default App;
// Input 组件
import React,{Component} from 'react'
import classNames from 'classnames'
import PropTypes from 'prop-types'
import Icon from '../Icon'
import './index.scss'
class Input extends Component{
constructor(props){
super(props)
this.state = {
focus: false,
innerValue: ''
}
}
static propTypes = {
value: PropTypes.string,
onChange: PropTypes.func,
size:PropTypes.string,
}
static defaultProps = {
size: 'middle',
onChange: () => {}
}
get isControl(){
return 'value' in this.props
}
get value() {
if(this.isControl){
return this.props.value
} else {
return this.state.innerValue
}
}
render() {
const {
focus
} = this.state
const {
icon,
children,
size,
prefix,
suffix,
onChange,
rule= new RegExp(),
message,
...rest
} = this.props
let cls = classNames({
input: true,
focus,
[`size-${size}`]: true,
'react-ui__input': true
})
return (
<div>
<div className={cls}>
{prefix && <Icon name={prefix}/>}
<input
value={this.value}
onFocus={e => {
this.setState({focus: true
})
}}
onBlur={e => {
this.setState({focus: false
})
}}
onChange={(e) => {
if(!this.isControl){
this.setState({
innerValue: e.target.value
})
}
this.props.onChange(e)
}}
/>
{suffix && <Icon name={suffix}/>}
</div>
<p>
{!rule.test(this.value) && message}
</p>
</div>
)
}
componentDidMount() {
this.setState({
innerValue: this.props.defaultValue
})
}
}
export default Input
// 受控
// 非受控
// Input 组件样式
$primaryColor: blue;
$warningColor: yellow
.react-ui__input{
border: 1px solid #d2d2d2;
display: inline-block;
input{
outline: none;
border: none;
}
&.focus{
border-color: blue;
}
&.size-large input{
line-height: 40px;
font-size: 18px;
}
&.size-small input{
line-height: 20px;
font-size: 14px;
}
&.middle input{
font-size: 12px;
line-height: 30px;
}
&--primary{
//background: $primaryColor;
color: #fff;
background-color: #1890ff;
border-color: #1890ff;
text-shadow: 0 -1px 0 rgba(0,0,0,0.12);
}
&--warning{
background: $warningColor;
}
}
4. 实现Table
// Table的应用
import React from 'react';
import './App.css';
import Table from './react-ui/Table/index1'
let dataSource=[
{
name:'ryan',age:'30',sex:'man',
},
{
name:'ryan2',age:'31',sex:'man',
},
{
name:'ryan3',age:'32',sex:'man',
}
]
class App extends React.Component{
render() {
return (
<div>
<Table
columns={[
{title: '姓名', dataIndex:"name",key: 'name', render(text, item, index){
return <div><a href='#'>{text} ? {item.age} + {index}</a></div>
}},
{title: '年龄', dataIndex:"age",key: 'age'},
{title: '性别', dataIndex:"sex",key: 'sex'},
]}
dataSource={dataSource}
/>
</div>
);
}
}
export default App;
// Table组件内部实现
import React from 'react';
import PropTypes from 'prop-types';
import './index.scss';
class ColumnItem extends React.Component {
render() {
const {
render = () => '占位符',
title
} = this.props.item;
return(
<th>{title}</th>
)
}
}
class Columns extends React.Component {
render() {
const {
columns
} = this.props;
return(
<thead>
<tr>
{columns.map(item => <ColumnItem item={item} key={item.key}/>)}
</tr>
</thead>
)
}
}
class DataSourceItem extends React.Component {
render() {
const {
columns,
dataItem,
index,
} = this.props;
const tds = columns.map((item) => <td key={item.dataIndex}>{item.render ? item.render(dataItem[item.dataIndex],dataItem,index) : dataItem[item.dataIndex]}</td>)
return(
<tr>
{tds}
</tr>
)
}
}
class DataSource extends React.Component {
render() {
const {
dataSource,
columns
} = this.props;
let trs = dataSource.map((item,index) => <DataSourceItem dataItem={item} index={index} columns={columns} key={item.name}/>);
return(
<tbody>
{ trs }
</tbody>
)
}
}
class Table extends React.Component {
static propTypes = {
columns:PropTypes.array,
dataSource: PropTypes.array
}
static defaultProps = {
columns: [],
dataSource: []
}
render() {
const {
columns,
dataSource,
...rest
} = this.props;
return(
<div>
<table border='1'>
<Columns columns={columns} />
<DataSource dataSource={dataSource} columns={columns}/>
</table>
</div>
)
}
}
export default Table;