button作为最常见的页面元素,几乎所有的UI库都会将其封装为一个基础组件。
在实际业务中,我们期望的是不用写css就能够得到一个满意样式的按钮,因此我们会将常用的几种应用场景提前封装好,使用时只需要传入对应的类型即可。
1<Button>default</Button>2<Button type="primary">primary</Button>3<Button type="warning">warning</Button>4<Button type="danger">danger</Button>
props中传入type,显示对应语义的样式。
10import React, { Component } from 'react';20import classnames from 'classnames';30import './style.scss';4050class Button extends Component {60static defaultProps = {70loading: false,80type: 'default', // default warning primary90}1011render() {12const { type, ghost, className, children, ...other } = this.props;1314const cls = classnames('button', {15[`button-${type}`]: true,16'button-ghost': ghost17}, className);18return (19<button className={cls}>20{children}21</button>22)23}24}2526export default Button;
10.button {20margin: 6px 4px;30cursor: pointer;40line-height: 1.6;50padding: 4px 15px;60border: 1px solid #d9d9d9;70border-radius: 4px;80color: #404040;90transition: 0.2s;10position: relative;11outline: none;1213&::after {14border-width: 0;15}1617i + span {18margin-left: 8px;19}2021span + i {22margin-right: 8px;23}2425&-primary {26background-color: #108ee9;27color: #FFF;28border: 1px solid #108ee9;29}3031&-warning {32background-color:orange;33color: #fff;34border: 1px solid orange;35}3637&-danger {38background-color: #f04134;39color: #fff;40border: 1px solid #f04134;41}42}
第二步,新增基础的交互元素
以default为例
新增hover样式
1&-default {2&:hover {3color: #108ee9;4border-color: #108ee9;5}6}
新增active样式
1&:active {2color: red;3border-color: red;4}
原则是hover的颜色比本色浅一点,active的颜色比本色深一点,这样会有比较好的视觉效果。
第三步:
点击效果。
10import React, { Component } from 'react';20import classnames from 'classnames';30import './style.scss';4050class Button extends Component {60static defaultProps = {70type: 'default', // default warning primary80}9010state = {11clicked: false12}1314clickHandler = (e) => {15const { onClick } = this.props;16this.setState({17clicked: true18})1920clearTimeout(this.timeout);21this.timeout = setTimeout(() => {22this.setState({ clicked: false })23}, 500);2425onClick && onClick(e);26}2728render() {29const { type, ghost, className, children, ...other } = this.props;30const { clicked } = this.state;3132console.log(clicked);3334const cls = classnames('button', {35[`button-${type}`]: true,36'button-ghost': ghost,37'button-clicked': clicked38}, className);39return (40<button41className={cls}42onClick={this.clickHandler}43{...other}44>45{children}46</button>47)48}49}5051export default Button;52
10&-clicked {20&:after {30display: block;40content: '';50position: absolute;60top: -1px;70left: -1px;80bottom: -1px;90right: -1px;10border-radius: inherit;11border: 0 solid #108ee9;12opacity: 0.4;13animation: buttonEffect .4s;14display: block;15}16}
1020@keyframes buttonEffect {30to {40opacity: 0;50top: -6px;60left: -6px;70bottom: -6px;80right: -6px;90border-width: 6px;10}11}12
思考:
如果让不同背景的颜色,点击之后的效果颜色与背景相同呢?
第四步:
集成了图标的按钮
10import React, { Component } from 'react';20import classnames from 'classnames';30import Icon from '../Icon';40import './style.scss';5060class Button extends Component {70static defaultProps = {80type: 'default', // default warning primary90}1011state = {12clicked: false13}1415clickHandler = (e) => {16const { onClick } = this.props;17this.setState({18clicked: true19})2021clearTimeout(this.timeout);22this.timeout = setTimeout(() => {23this.setState({ clicked: false })24}, 500);2526onClick && onClick(e);27}2829render() {30const { type, ghost, className, children, icon, ...other } = this.props;31const { clicked } = this.state;3233console.log(clicked);3435const cls = classnames('button', {36'button-clicked': clicked,37[`button-${type}`]: true,38'button-ghost': ghost,39}, className);4041const iconNode = icon ? <Icon type={icon} /> : null;42return (43<button44className={cls}45onClick={this.clickHandler}46{...other}47>48{iconNode}49<span>{children}</span>50</button>51)52}53}5455export default Button;56
思考题:
现在我们需要当传入的icon为loading时,需要让图标能够选择起来,并且按钮处于
disabled
状态,并同时修改按钮样式为对应的disabled状态,应该如何实现呢?