react-hook手动封装可搜索远程数据的搜索框
废话不多说,直接上代码!!!
1 import React, { useState, useRef } from 'react' 2 import { SearchOutlined } from '@ant-design/icons' 3 import './styles.less' 4 5 const arr = [ // 模拟数据 6 { id: 0, name: '张三15324680666' }, 7 { id: 1, name: '李四13603885241' }, 8 { id: 2, name: '王五18939752514' }, 9 { id: 3, name: '王珊15525242514' }, 10 { id: 4, name: '刘振19852524868' }, 11 { id: 5, name: '王啊15525242514' }, 12 { id: 6, name: '王我15525242514' }, 13 { id: 7, name: '王屙15525242514' }, 14 { id: 8, name: '王去15525242514' }, 15 ] 16 17 export default function Test() { 18 19 const putEle = useRef() // 获取输入框元素 20 const [iconS, setIconS] = useState(false) // 搜索按钮的显示隐藏状态 21 const [openS, setOpenS] = useState(false) // 数据列表的状态 22 const [data, setData] = useState([]) // 搜索完之后的数据存放 23 const [enterI, setEnterI] = useState(null) // 鼠标移入数据列表 24 25 const putEnter = () => setIconS(true) 26 27 const putLeave = () => { setIconS(false), setOpenS(false) } 28 29 const searchClick = () => { // 点击搜索 30 let value = putEle.current.value 31 if (value) { 32 const itemArr = [] 33 arr.forEach(v => { 34 if (v.name.indexOf(value) != -1) { 35 itemArr.push(v) 36 } 37 }) 38 setData(itemArr) 39 setOpenS(true) 40 } else { setOpenS(false) } 41 } 42 43 const itemStylesAdd = (index) => setEnterI(index) // 数据列表划过添加样式 44 45 const itemClick = (value) => { 46 putEle.current.value = value 47 setOpenS(false) 48 setData([]) 49 } 50 51 const TextLeave = () => setEnterI(-1) 52 53 return ( 54 <div className="pages-test"> 55 <div onMouseEnter={putEnter} onMouseLeave={putLeave} className="input-box"> 56 <input type="text" ref={putEle} /> 57 {openS ? <div onMouseLeave={TextLeave} className="sourse-text"> 58 { 59 data.length ? data.map((v, i) => { 60 return ( 61 <div 62 key={i} 63 className={enterI === i ? "data-item itemStyle" : "data-item"} 64 onMouseEnter={() => { itemStylesAdd(i) }} 65 onClick={() => { itemClick(v.name) }} 66 > 67 {v.name} 68 </div> 69 ) 70 }) : <div className="not-found">不好意思,没有搜索结果</div> 71 } 72 </div> : null} 73 {iconS ? <SearchOutlined onClick={searchClick} /> : null} 74 </div> 75 </div> 76 ) 77 }
样式代码
.pages-test { .input-box { width: 200px; display: inline-block; position: relative; input { width: 200px; height: 32px; border: 1px solid #D9D9D9; border-radius: 3px; padding-left: 5px; } .sourse-text { width: 200px; height: 150px; background: white; border: 1px solid #D9D9D9; position: absolute; bottom: -150px; overflow: auto; .data-item { width: 100%; height: 30px; line-height: 30px; padding-left: 10px; cursor: pointer; } .itemStyle { background: #C8E0F0; } .not-found { text-align: center; line-height: 140px; } } .anticon-search { position: absolute; right: 3%; top: 15%; font-size: 22px; cursor: pointer; } } } /*滚动条样式*/ ::-webkit-scrollbar { /*滚动条整体样式*/ width: 4px; /*高宽分别对应横竖滚动条的尺寸*/ height: 4px; } ::-webkit-scrollbar-thumb { /*滚动条里面小方块*/ border-radius: 5px; -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2); } ::-webkit-scrollbar-track { /*滚动条里面轨道*/ -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2); border-radius: 0; background: rgba(0, 0, 0, 0.1); }