初始数据结构:
const options = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
结构:我们每次点击一个面板的时候会显示另一个面板,初始化的时候始终显示一个面板,所以我们可以把我们开始的数据结构进行修改,我们可以修改成一个二维数组,每次点击的时候在这个二维数组里把当前项的children再添加进这个数组里,也就是一开始的时候把所有的数据都放在数组里
[options,item.children]
const Cascader: React.FunctionComponent<cascaderOptions> = (props) => {
const [visible, setVisible] = useState(false)
const [list, setList] = useState<doubleArrOptions | any>([])
const initOptions: Options | doubleArrOptions = props.options
const selectInit = () => {
setInputValue('')
initOptionList()
}
const initOptionList = () => {
setList([[...props.options]])
}
useEffect(() => {
window.addEventListener('click', onClickDocument, false)
if (props.options && props.options.length > 0) {
(!defaultValue || defaultValue.length === 0) && initOptionList()
}
props.defaultValue && setInputValue(props.defaultValue.join('/'))
return () => window.removeEventListener('click', onClickDocument)
}, [])
return (
<C.Provider value={{list, setList, initOptions, onChange, setInputValue, setVisible, defaultValue, fieldNames}}>
<div className={sc('')} ref={wrapperRef}>
<div className={sc('wrapper')} onMouseEnter={() => setVisibleClose(true)}
onMouseLeave={() => setVisibleClose(false)}
>
<Input onClick={(e) => onClick(e)} onChange={onInputChange} value={inputValue} readOnly placeholder={props.placeholder}
style={{width: '300px'}}
/>
{
inputValue && visibleClose ?
<Icon name="close" onClick={selectInit}/> :
<Icon name="bottom" className={sc({'icon-active': visible})}/>
}
</div>
<div className={sc({'menus': true, 'visible': visible})}
>
<Menus options={list}/>
</div>
</div>
</C.Provider>
)
}
const Menus: React.FunctionComponent<cascaderOptions> = ({options}) => {
let copyList = JSON.parse(JSON.stringify(list))
const onClickList = (item: cascaderProp, index: number) => {
// 如果点击的是第一层就把所有的数据初始化,否则就截取第0项到当前这项
copyList = index === 0 ? [[...initOptions]] : copyList.slice(0, index + 1)
setList(copyList)
}
return (
<Fragment>
{list.map((node: Options, index: number) =>
<ul className={sc('menu')} key={index}>
{node.map((menu: cascaderProp) =>
<li className={sc({'menu-item': true, 'active': menu.active === true})} key={menu[fieldNames.label]} onClick={() => onClickList(menu, index)}>
{menu[fieldNames.label]}
{menu[fieldNames.children] && menu[fieldNames.children].length > 0 ? <Icon name="right" className={sc('menu-item-icon')}/> : null}
</li>
)}
</ul>
)}
</Fragment>
)
}
网友评论