今天有这样一个需求:
注意:每次点击每个层级。点击的项高亮。层级之间相互不干扰。
最初的实现思路:
设置一个currentIndex。点击该项的时候通过currentIndex==item对应的index就ok了。但是问题是层级很多呢?那需要在useState中维护多个index。一一对应、这样非常不科学。
后来有了个思路:
在useState中定义一个数组 ids= [a,b,c,d]分别表示各个层级的当前点击时的项目id。每次点击的时候更改这个数组对应的id。而我们高亮的判断条件就是当前点击项的id是否在我们记录跟踪的数组ids中。如果在则给其添加高亮样式。
代码如下:
定义数据
const [ids,setIds]=useState([]) //该数组记录每次点击时各个层级点击的当前项id
const [arr1,setArr1]=useState(oneList) //第一层数据
const [arr2,setArr2]=useState(tList) //第二层数据
const [arr3,setArr3]=useState(treList) //第三层数据
dom结构
<div className="table-wrap">
<div className="attr-head">
<div className="table-head">一级类目</div>
<div className="tree-list">
{arr1.map(item=>{
return (
<div className={classnames("list-item",{"active":ids.includes(item.id)})} onClick={()=>handlerClickItem("1",item)}>
<div className="list-item-name">{item.name}</div>
<div className="list-item-icon">{item.children?<Iconfont type="icon-xiangyou"></Iconfont>:''}</div>
</div>
)
})}
</div>
</div>
<div className="value-head">
<div className="table-head">二级类目</div>
<div className="tree-list">
{arr2.map(item=>{
return (
<div onClick={()=>handlerClickItem("2",item)} className={classnames("list-item",{"active":ids.includes(item.id)})}>
<div className="list-item-name">{item.name}</div>
<div className="list-item-icon">{item.children?<Iconfont type="icon-xiangyou"></Iconfont>:''}</div>
</div>
)
})}
</div>
</div>
<div className="catagory-head">
<div className="table-head catagory-table-head">三级类目</div>
<div className="tree-list">
{arr3.map(item=>{
return (
<div onClick={()=>handlerClickItem("3",item)} className={classnames("list-item",{"active":ids.includes(item.id)})}>
<div className="list-item-name">{item.name}</div>
<div className="list-item-icon">{item.children?<Iconfont type="icon-xiangyou"></Iconfont>:''}</div>
</div>
)
})}
</div>
</div>
</div>
注意:我们在点击事件里传入了一个参数用来表示当前点击的是那个层级。好对应更改ids
逻辑处理:
const handlerClickItem=(type,item)=>{
let newIds=JSON.parse(JSON.stringify(ids));
switch(type){
case "1":
newIds[0]=item.id;
break;
case "2":
newIds[1]=item.id;
break;
case "3":
newIds[0]=item.id;
break;
default:
}
setIds(newIds)
}
注意这里我们做了一个深拷贝ids。对于useState的更新。如果是同一个引用地址。则无法更新。通过深拷贝。我们得到一个全新的引用地址
坦白说。react的更新机制,的确没有vue的双向绑定来的直接简单。
|