成果样式: 选中样式: 流程: 1:接收默认值,在页面显示出来(传入左右移动组件) 2:可以新增(有正则校验) 3:将最终数据传入父组件
组件核心代码:
import React, { useEffect, useState, memo } from 'react'
import RSButton from '@com/RSButton';
import RSInput from '@com/RSInput';
import { message } from 'antd';
import './index.less'
const LeftOrRightMoveCom = (props) => {
const title = props.title || "";
const AddReg = props.AddReg || "";
let [keyAndValue, setKeyAndValue] = useState("");
let [keyAndValueList, setKeyAndValueList] = useState([]);
const addOrDelBtn = (info) => {
if (info === 'add') {
if (!keyAndValue) {
message.warning(`请输入${title}`)
return false
}
if (AddReg && !AddReg.test(keyAndValue)) {
message.warning(`${title}格式不正确`)
return false
}
if (keyAndValueList.find(i => i.value === keyAndValue)) {
message.warning(`请保证输入唯一性:${keyAndValue}`)
return false
}
setKeyAndValueList(state => [...state, {
key: Math.random()*2,
value: keyAndValue,
active: false
}])
setKeyAndValue("")
} else if (info === 'del') {
keyAndValueList = keyAndValueList.filter(i => i.active === false)
setKeyAndValueList(_ => [...keyAndValueList])
}
}
const clickLiItem = (liItem) => {
keyAndValueList.map(i => {
i.active = false
if (i.key === liItem) {
i.active = true
}
return i
})
setKeyAndValueList(_ => [...keyAndValueList])
}
useEffect(() => {
props.getListFun(keyAndValueList)
}, [keyAndValueList])
useEffect(() => {
let defaultList = props.defaultList || []
let newDefaultList = defaultList.map((item, idx) => {
return {
value: item,
key: Math.random()*2,
active: false
}
})
setKeyAndValueList(_ => newDefaultList)
}, [props.defaultList])
return (
<div className="search-input-row" style={{ display: 'flex', marginLeft: '0px', marginBottom: "10px", alignItems: 'flex-start' }}>
<RSInput placeholder="请输入" title={title} value={keyAndValue} onChange={e => setKeyAndValue(e.target.value)} />
<span style={{ marginRight: '50px' }}></span>
<div>
<RSButton rsType="noIcon" title="增加>>>" onClick={() => { addOrDelBtn('add') }}></RSButton>
<br style={{ marginBottom: '30px' }}></br>
<RSButton rsType="noIcon" color="#108EE9" title="<<<删除" onClick={() => addOrDelBtn('del')}></RSButton>
</div>
<span style={{ marginRight: '50px' }}></span>
<ul className="addOrDelUl" style={{ border: '1px solid #ccc', width: '250px', height: '120px' }}>
{
keyAndValueList.map((item, index) => {
return (
<li style={{ cursor: "pointer" }} key={item.key + index.toString()} title={item.value} onClick={() => clickLiItem(item.key)} className={item.active ? 'liActive' : ''}
>{item.value}
</li>
)
})
}
</ul>
</div>
)
}
export default memo(LeftOrRightMoveCom)
css:
.context{
width: 100%;
height: 100%;
}
.addOrDelUlShow{
overflow: hidden;
overflow-y: auto;
border-radius: 4px;
li{
list-style: none;
font-size: 14px;
padding-left: 10px;
padding-top: 4px;
color: black;
line-height: 18px;
}
}
.addOrDelUl{
overflow: hidden;
overflow-y: auto;
border-radius: 4px;
li{
list-style: none;
font-size: 16px;
padding-left: 10px;
padding-top: 4px;
color: black;
line-height: 24px;
}
li:hover{
background-color: #ccc;
}
.liActive{
background-color: #ccc;
color: #fff;
}
}
.zoneUpload{
width:100px!important
}
.zonefilechangeInput{
.rsinput-title{
width: 30px!important;
min-width:30px;
}
}
使用:
<LeftOrRightMoveCom
getListFun={this.getListFun1}
defaultList={["数学", "语文", '英语']}
AddReg={new RegExp('(^\\/)([a-z0-9._@\\-\\/]+)([^\\/]$)', 'i')}
title="学习" />
<LeftOrRightMoveCom
getListFun={this.getListFun2}
AddReg={new RegExp('(^\\/)([a-z0-9._@\\-\\/]+)([^\\/]$)', 'i')}
defaultList={["唱歌", "跳舞", '踢足球']}
title="爱好" />
回调函数拿到最新的list,可以自行处理数据格式
getListFun1 = (list) => {
let dataDefault = list.reduce((str, item, index) => {
return str = [...str, item.value]
}, [])
this.setState({
dataDefault: dataDefault ? dataDefault : ""
})
}
getListFun2 = (list) => {
let appDefault = list.reduce((str, item, index) => {
return str = [...str, item.value]
}, [])
this.setState({
appDefault: appDefault ? appDefault : ""
})
}
|