为什么说使用React就是提高生产力呢?
我也不想多做解释了,大概类如以下这样的界面,用React实现,连HTML、JS、交互,250行不到,额外使用了jQuery和lodash。
完成效果大致如下:
以下是源代码:
var React = require('react'); var ReactDOM = require('react-dom'); const PropTypes = React.PropTypes; var $ = jQuery; class GoodsSearchInput extends React.Component { static defaultProps = { min: 2,max: 20,name: '',url: location.href,delay: 1000,debug: false,selectId: 0,selectName: '',tip: '请输入关键字' }; static propTypes = { min: PropTypes.number,max: PropTypes.number,url: PropTypes.string,delay: PropTypes.number }; constructor(props) { super(props); this.state = { value: this.props.value,category: '',results: {},searching: {},isHide: false,isSearch: true,selected: { id: this.props.selectId,name: this.props.selectName } }; } tick = null; clearTick() { if (this.tick != null) clearTimeout(this.tick); return this; } resetTick() { this.clearTick(); let delay = this.props.delay < 300 ? 300 : this.props.delay; this.tick = setTimeout(() => { this.search().then((result) => { }).catch((result) => { }); },this.props.delay); return this; } changeInput(value) { if (this.state.isSearch) { if (value.length >= this.props.min) { this.resetTick(); } else { this.clearTick(); } } this.setState({ value: value,isSearch: true }); } getValue() { return this.state.value; } search() { let me = this,state = this.state,value = this.getValue(),results = state.results,searching = state.searching; return new Promise((resolve,reject) => { if (typeof results[value] !== 'undefined') { if (results[value] === false) resolve(results[value]); else reject(results[value]); } else if (!searching[value]) { searching[value] = 1; me.setState({searching: searching}); $.ajax({ url: this.props.url,data: { search: value // category: value },dataType: 'json' }).done(function (data) { if (!data.count || data.count <= 0) { results[value] = false; searching[value] = 3; me.setState({ results: results,searching: searching,isHide: false }); reject(false); } else { results[value] = data; searching[value] = 2; me.setState({ results: results,searching: searching }); resolve(results[value]); } }).fail(function () { results[value] = false; searching[value] = 3; me.setState({ results: results,searching: searching }); reject(false); }); } }); } hideResult() { this.setState({isHide: true}); } showResult() { this.setState({isHide: false}); } selectItem(row) { this.setState({ value: row.name,selected: row,isHide: true,isSearch: false }); } isSelected() { return this.state.selected.id > 0; } cleanSelected() { this.setState({ value: '',selected: { id: 0,name: '' } }); } renderState() { let value = this.getValue(),searching = this.state.searching; switch (searching[value]) { case 1 : return <span className="searching">{`搜索“${this.state.value}”中`}</span>; break; case 2 : let result = this.state.results[value]; if (this.state.isHide) return <span className="success"> {`搜索“${this.state.value}”共${result.count}条结果`} <a onClick={() => this.showResult()} className="show">显示结果</a> </span>; else return <span className="success"> {`搜索“${this.state.value}”共${result.count}条结果`} </span>; break; case 3 : return <span className="failure">{`搜索“${this.state.value}”无结果`}</span>; break; default : return this.props.tip; } } renderResult() { let result = this.state.results[this.getValue()]; if (!result || result.count <= 0) { return ''; } else if (!this.state.isHide) { return <div className="search-result abs"> <div> {result.data.map((row) => { return <div key={'search_result_' + row.id} className="search-item" onClick={() => this.selectItem(row)}> <div className="search-icon"><img src={row.img}/></div> <div className="search-info"> <div><strong>{row.name}</strong></div> <span className="goods-price">{row.price}</span> </div> </div>; })} </div> <div className="search-hide" onClick={() => this.hideResult()}>隐藏</div> </div>; } } renderHidden() { if (this.props.name) { return <input type="hidden" name={this.props.name} value={this.state.selected.id}/> } } render() { return <div className=""> <div className="search-input-Box"> <div className="uk-form-icon input"> <i className="uk-icon-search"/> <input type="text" value={this.state.value} min={this.props.min} maxLength={this.props.max} placeholder={`输入最少${this.props.min}个字符`} onChange={(event) => this.changeInput(event.target.value)} className="af-input" /> </div> <button type="button" className="uk-button uk-button-primary" title="清除选中结果" disabled={!this.isSelected()} onClick={() => this.cleanSelected()}> <i className="uk-icon-remove"/> </button> </div> {this.renderHidden()} <div className="rel"> {this.renderResult()} </div> <div className="af-tip"> {this.renderState()} </div> </div>; } } $.fn.goodsSearchInput = function (props) { if (!this.get(0)) throw new ReferenceError('Invalid DOM Element!'); else if (!this.prop('goods-search-input')) { props = props || {}; props = _.merge(props,this.data()); let input = ReactDOM.render(<GoodsSearchInput {...props}/>,this.get(0)); this.prop('goods-search-input',input); } return this.prop('goods-search-input'); }; module.exports = GoodsSearchInput;
其实严格来说,还可以再优化一下,做成一个通用版本,代码也可以再少些,不过因为做的时候,是赶着项目的需求做的,所以暂时就不折腾了。
做的时候是命名为GoodsSearchInput,其实事后基本上所有自动检索部分的输入框都用了他。
<div id="test"></div> <script type="text/javascript"> (function($) { $('#test').goodsSearchInput({ name: 'test',url: 'http://localhost/test/search_goods.PHP',value: '商业包装设计',}); })(jQuery) </script>
<?PHP $goods = Goods::getCacheOne($value); ?> <div id="<?PHP echo $attr['id']; ?>" goods-search-input class="af-min-height" data-url="<?PHP echo linkUri('ajax/search_goods',['supplier_id' => $this->supplier->id]); ?>" data-name="<?PHP echo $attr['name']; ?>" data-value="<?PHP echo $goods->isExists() ? $goods->name : '' ?>" data-select-id="<?PHP echo $goods->isExists() ? $goods->id : 0 ?>" data-select-name="<?PHP echo $goods->isExists() ? $goods->name : '' ?>"></div>
写完调试完上述代码,用了1个小时左右的时间,增加样式调试0.5小时。剩下来的时间,可以去b站补两集番。
用React就是这样简单,如果你还没用,你out了。