赞
踩
实现: (待重构,代码冗余复杂) (1)插槽内容的重构 因为this.props.children直接显示,不能给插槽中的组件传递参数但能获取标签内容,所以进行遍历生成对应内容 (2)插槽中的复选框组件,统一使用父组件的点击方法,统一改变复选框的状态,并在父组件中初始化所有复选框状态 (3)点击方法会改变父组件中的统一设置的所有复选框的对应状态,使用传递给父组件的方法,向外暴露复选框的状态 (4)动画的效果主要使用了rotate 和 scale 使用: 方式一:插槽统一管理 <CheckBox onChange={fn} 回调第一个参数是所有复选框的状态 boxSize='30px' 框的大小 graphSize='30px' 框内图标的大小 color='red' 框的颜色 > <CheckItem checkd 是否选中 label='' 文本内容 boxClick:func, 点击回调,当通过插槽使用时,第一个参数是索引,第二个是状态,单独使用第一个undefined,第二个为当前状态 checked:bool, 是否选中 labelSize:'npx', 标签文件大小 graphSize:'图案大小', boxSize:'按钮大小', color:'背景颜色' ><CheckItem /> ... </CheckBox/> 方式二:单独使用 <CheckItem checkd 是否选中 label='' 文本内容 ... ><CheckItem />
效果图:
点击后回调参数:
目录结构:
代码示例:
使用:
import React,{Component} from 'react' import CheckBox from './checkBox' import CheckItem from './checkBox/checkItem' class App extends Component{ _onBoxChange(info) { console.log(info); } render() { return( <div> <CheckBox onChange={this._onBoxChange.bind(this)} boxSize='30px' graphSize='30px' color='red'> <CheckItem label='内容1' checked></CheckItem> <CheckItem label='内容2'></CheckItem> <CheckItem label='内容3' checked></CheckItem> </CheckBox> </div> ) } } export default App
checkBox:
import React,{Component} from 'react' import CheckItem from './checkItem' import './index.css'; import PropTypes from 'prop-types'; class App extends Component{ static propTypes={ onChange:PropTypes.func, size:PropTypes.string, graphSize:PropTypes.string, color:PropTypes.string } static defaultProps={ boxSize:'20px', labelSize:'16px', graphSize:'16px', color:'#409EFF', onChange:()=>{} } state={ boxes:[], } //改变点击态 _boxClick(index,checked) { this.state.boxes[index]['checked']=checked; this.props.onChange(this.state.boxes); } componentDidMount() { this.props.children.forEach((item,index)=>{ this.state.boxes.push({ label:item.props.label, index, checked:item.props.checked }) }) this.props.onChange(this.state.boxes); } render() { const {boxSize,labelSize,graphSize,color} =this.props return( <div className='jf-box-container'> <div className='jf-box-checkBox'> { this.props.children.map((item,index)=>{ return <CheckItem {...item.props} color={color} boxSize={boxSize} labelSize={labelSize} graphSize={graphSize} key={index} boxIndex={index} boxClick={this._boxClick.bind(this)}></CheckItem> }) } </div> </div> ) } } export default App
对应css:
.jf-box-container {
display: inline-block;
}
.jf-box-checkBox {
display: flex;
}
checkItem:
import React,{Component} from 'react' import PropTypes from 'prop-types'; import './index.css' class App extends Component{ state={ boxChecked:false, } static propTypes={ label:PropTypes.string, boxClick:PropTypes.func, boxIndex:PropTypes.number, checked:PropTypes.bool, labelSize:PropTypes.string, graphSize:PropTypes.string, boxSize:PropTypes.string, color:PropTypes.string } static defaultProps = { boxClick:()=>{}, } componentDidMount() { if (this.props.checked) { this._changeUi(); } } //只是改变样式,不传递回调,避免使用checked属性后,每改变一次就都会传递参数,只有点击才会传递 _changeUi() { this.setState({ boxChecked:!this.state.boxChecked, }) } _changeAndSend() { this.props.boxClick(this.props.boxIndex,!this.state.boxChecked) this.setState({ boxChecked:!this.state.boxChecked, }) } //监听外界改变checked时回调 componentWillReceiveProps(props) { if (props.checked != undefined) { props.checked ? this.state.boxChecked = false : this.state.boxChecked = true; this._changeUi() } } render() { let {boxChecked}=this.state; const {label,boxSize,labelSize,graphSize,color} = this.props; return( <div className='jf-box-item'onClick={(e)=>{this._changeAndSend()}}> <div className='jf-box-item-layout'> <div className={`jf-box ${boxChecked&&'jf-box-checked'}`} style={boxChecked?{backgroundColor:color,width:boxSize,height:boxSize,borderColor:color}:{width:boxSize,height:boxSize}}> <span className={boxChecked?'jef-cont-checked':'jef-cont'} style={{fontSize:graphSize}}>√</span> </div> <span className='jf-label' style={{fontSize:labelSize}}>{label}</span> </div> </div> ) } } export default App
对应css:
.jf-box-item { cursor: pointer; align-items: center; display: inline-block; align-items: center; -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .jf-box-item-layout { display: flex; align-items: center; } .jf-box { width: 20px; height: 20px; color: white; display: flex; justify-content: center; align-items: center; border: solid 1px #ccc; border-radius: 20%; transition: border-color 0.5s cubic-bezier(0.71, -0.46, 0.29, 1.46), background-color 0.5s cubic-bezier(0.71, -0.46, 0.29, 1.46); } .jf-box > span { transition: 0.2s; font-size: 16px; } .jef-cont { transform: rotate(-45deg) scale(0); } .jf-label { font-size: 16px; } .jf-box-checked { background-color: #409eff; border: solid 1px #409eff; } .jef-cont-checked { transform: rotate(0deg) scale(1); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。