Open lulujianglab opened 5 years ago
相信使用过React.js的小伙伴都应该知道其数据双向绑定的灵活性,在处理表单,人机交互方面都具能发挥极大的优势,而且实现起来也比较方便
最近在项目中刚好用到了这系列操作,下面以类似于单选框、复选框和下拉框为例介绍他们在ant-design-pros中的具体实现方式
在项目中我们经常会遇到类似单选事件的小功能,比如点击或悬浮的元素高亮,页面上有很多的item元素,要实现点击或者悬浮到哪个就哪个高亮
用jq实现的话,就是选中的元素给加个addClass的事件,添加active的样式,然后它的兄弟元素removeClass,去掉active样式
addClass的
removeClass
同样的,用react实现,我们可以用相同的思路,比如用一个currentIndex,通过它来判断是在哪个元素实现切换的,而currentIndex的值又可以通过选中元素的某个元素属性来动态改变
currentIndex
class Radio extends PureComponent { state= { currentIndex: null, value: null } setCurrentIndex = (e) => { this.setState({ currentIndex: parseInt(e.currentTarget.getAttribute('index'), 10) }) } handleChange = (e) => { this.setState({ value: e.target.value }) } render () { const arr = ['京东超市', '天猫超市', '京东生鲜', '京东到家', '果蔬好', '盒马生鲜', '无人超市', '每日生鲜'] const itemList = arr.map((item, index) => { return ( <li key={index} className={`${styles.item} ${this.state.currentIndex === index ? styles.active : ''}`} index={index} onClick={this.setCurrentIndex} > {item} </li> ) }) return ( <Card title="单选列表" bordered={false} className={styles.main}> <div className={styles.content}> <div className={styles.top}> <div className={styles.name}>点击或悬浮选中的li高亮:</div> <ul className={styles.list}>{itemList}</ul> </div> <div className={styles.bottom}> <div className={styles.name}>您的性别为:</div> <div className={styles.list}> <label className={styles.item}><input type="radio" name='gender' value="男生" onChange={this.handleChange}/>男生</label> <label className={styles.item}><input type="radio" name='gender' value="女生" onChange={this.handleChange}/>女生</label> </div> <div className={styles.sex}>性别: {this.state.value}</div> </div> </div> </Card> ) } }
总的来说,就是生成这些li的时候给元素添加一个index标志位,然后通过相应的点击事件,把这个index用e.currentTarget.getAttribute('index')取出来,然后去设置currentTarget的值,再通过赋给选中的css的active样式就可以了
e.currentTarget.getAttribute('index')
currentTarge
在页面中,有时候会根据用户的一些操作更新属性值,但不同的对象间的操作就涉及到对多个值的状态管理,这些可变的状态通常都保存在组件的状态属性中,并且只能用setState()方法更新
setState()
复选事件和单选事件类似,也需要通过监听各个标签元素的点击或者悬浮等事件来实现
class Checkbox extends PureComponent { state = { fruit: [], value: [] } handleChange = (e) => { let item = e.target.value let items = this.state.fruit.slice() let index = items.indexOf(item) index === -1 ? items.push(item) : items.splice(index, 1) this.setState({fruit: items}) } onclickIcon = (e) => { let item = parseInt(e.currentTarget.getAttribute('index'), 10) let items = this.state.value.slice() let index = items.indexOf(item) index === -1 ? items.push(item) : items.splice(index,1) this.setState({ value: items }) } render() { const listArr = ['羽绒服', '裙子', '帽子', '围巾'] return ( <Card title="多选列表" bordered={false} className={styles.main}> <div className={styles.content}> <div className={styles.left}> <div className={styles.title}>Choose fruit : </div> <div className={styles.list}> <label className={styles.item}><input type="checkbox" name="fruit" value="apple" onChange={this.handleChange}/>apple</label> <label className={styles.item}><input type="checkbox" name="fruit" value="banana" onChange={this.handleChange}/>banana</label> <label className={styles.item}><input type="checkbox" name="fruit" value="pear" onChange={this.handleChange}/>pear</label> </div> <div>Choosen : {this.state.fruit.join('-')}</div> </div> <div className={styles.right}> <div className={styles.tag}>点亮我的喜欢:</div> <ul className={styles.card}> { listArr.map((item,index) => { return ( <li key={index} className={styles.item} index={index} onClick={this.onclickIcon} > <svg className={`${styles.svg} ${this.state.value.indexOf(index) === -1? styles.icon : styles.iconColor}`} aria-hidden="true"> <use xlinkHref={this.state.value.indexOf(index) === -1? "#icon-lovetaoxin" : "#icon-shixintaoxin"}></use> </svg> <span to='#' target="_blank" className={styles.text}>{item}</span> </li> ) }) } </ul> </div> </div> </Card> ) } }
总的来说,我们通过在组件状态state中定义数组,存放选中的信息,主要是通过先在li元素中添加index标志位,然后通过相应事件的触发,把这个index用e.currentTarget.getAttribute('index')取出来,存放到state中定义的数组中
需要注意的是,在更新value时,必须使用setState函数,否则代码不会被重新渲染,在return中显示已选中的选项不会实时更新
setState
下拉的实现方式和单选、复选有些类似,而且在ant-design中也有下拉Dropdown的组件,可以复用加以修改,可以直接看例子说明
class NewDropdown extends PureComponent { state = { value: 'basketball' } handleChange = (e) => { this.setState({ value: e.target.value }) } handleMenuClick = ({ key }) => { if (key === 'radio') { router.push('/selector/radio'); return; } if (key === 'checkbox') { router.push('/selector/checkbox'); return; } if (key === 'dropdown') { return; } }; render () { const menu = ( <Menu className={styles.menu} selectedKeys={[]} onClick={this.handleMenuClick}> <Menu.Item key="radio"> <Icon type="user" /> <FormattedMessage id="menu.selector.radio" defaultMessage="radio" /> </Menu.Item> <Menu.Item key="checkbox"> <Icon type="setting" /> <FormattedMessage id="menu.selector.checkbox" defaultMessage="checkbox" /> </Menu.Item> <Menu.Item key="dropdown"> <Icon type="close-circle" /> <FormattedMessage id="menu.selector.dropdown" defaultMessage="dropdown" /> </Menu.Item> </Menu> ); return ( <Card title="下拉列表" bordered={false} className={styles.main}> <div className={styles.content}> <div className={styles.left}> <label className={styles.select}>choose favorite sports: <select value={this.state.value} onChange={this.handleChange}> <option value="running">running</option> <option value="basketball">basketball</option> <option value="skiing">skiing</option> </select> </label> <div className={styles.chosen}>chosen: {this.state.value}</div> </div> <div className={styles.right}> <Dropdown overlay={menu}> <span className={styles.action}> <span className={styles.name}>查看示例</span> </span> </Dropdown> </div> </div> </Card> ) } }
总的来说,是通过在组件状态中设置一个value值,并在return中的select标签中使用,上述实现的是一个默认选中的功能
在用react实现表单时,其原理都是相同的,利用一个组件状态state来存储选中信息,然后监听各个标签元素的点击、悬浮、切换等事件,并在响应函数中更新组件状态
相信使用过React.js的小伙伴都应该知道其数据双向绑定的灵活性,在处理表单,人机交互方面都具能发挥极大的优势,而且实现起来也比较方便
最近在项目中刚好用到了这系列操作,下面以类似于单选框、复选框和下拉框为例介绍他们在ant-design-pros中的具体实现方式
单选事件
在项目中我们经常会遇到类似单选事件的小功能,比如点击或悬浮的元素高亮,页面上有很多的item元素,要实现点击或者悬浮到哪个就哪个高亮
用jq实现的话,就是选中的元素给加个
addClass的
事件,添加active的样式,然后它的兄弟元素removeClass
,去掉active样式同样的,用react实现,我们可以用相同的思路,比如用一个
currentIndex
,通过它来判断是在哪个元素实现切换的,而currentIndex
的值又可以通过选中元素的某个元素属性来动态改变效果图
代码
总的来说,就是生成这些li的时候给元素添加一个index标志位,然后通过相应的点击事件,把这个index用
e.currentTarget.getAttribute('index')
取出来,然后去设置currentTarge
t的值,再通过赋给选中的css的active样式就可以了复选事件
在页面中,有时候会根据用户的一些操作更新属性值,但不同的对象间的操作就涉及到对多个值的状态管理,这些可变的状态通常都保存在组件的状态属性中,并且只能用
setState()
方法更新复选事件和单选事件类似,也需要通过监听各个标签元素的点击或者悬浮等事件来实现
效果图
代码
总的来说,我们通过在组件状态state中定义数组,存放选中的信息,主要是通过先在li元素中添加index标志位,然后通过相应事件的触发,把这个index用
e.currentTarget.getAttribute('index')
取出来,存放到state中定义的数组中需要注意的是,在更新value时,必须使用
setState
函数,否则代码不会被重新渲染,在return中显示已选中的选项不会实时更新下拉事件
下拉的实现方式和单选、复选有些类似,而且在ant-design中也有下拉Dropdown的组件,可以复用加以修改,可以直接看例子说明
效果图
代码
总的来说,是通过在组件状态中设置一个value值,并在return中的select标签中使用,上述实现的是一个默认选中的功能
在用react实现表单时,其原理都是相同的,利用一个组件状态state来存储选中信息,然后监听各个标签元素的点击、悬浮、切换等事件,并在响应函数中更新组件状态