在data.d.ts中
interface RevolvingProps {
getValues: (val) => void // 传给父组件 搜索框中的值
list // 父组件传入走马灯的数据
values?: string // 父组件传过来的值 (搜索框中)
urlSearch?: string // 父组件传过来的搜索面板路由地址
width?: number // 宽度
}
export type { RevolvingProps }
在index.tsx中渲染
import React, { useEffect, useRef, useState } from 'react'
import type { RevolvingProps } from './data'
import { ContentArea } from './styled'
import { useDebounce, useUpdateEffect } from 'ahooks'
import { SearchBar } from 'antd-mobile'
import { useNavigate } from 'react-router-dom'
const RevolvingDoor: React.FC<RevolvingProps> = (props) => {
const navigate = useNavigate()
const { getValues, list, values, urlSearch, width } = props
const [value, setValue] = useState(undefined) as any
const debouncedValue = useDebounce(value, { wait: 1000 }) // 用来处理防抖值的 Hook。
const [status, setStatus] = useState(false)
useEffect(() => {
if (values) {
setValue(values)
}
}, [values])
let timer: any = null
const contentBox = useRef<any>()
const parent = useRef<any>()
const parentTwo = useRef<any>()
const handleSearch = (val: any) => {
setValue(val)
}
useUpdateEffect(() => {
getValues(debouncedValue) // 返回给父组件的值
}, [debouncedValue])
useEffect(() => {
if (
list?.length &&
contentBox.current &&
parent.current &&
parentTwo.current
) {
parentTwo.current.innerHTML = parent.current.innerHTML
const autoScrollLine = () => {
if (!contentBox.current) {
return
}
/*判断滚动内容是否已经滚完,滚完了则滚动的值重新设置到0
否则就每隔30毫秒向上滚动1px*/
if (contentBox.current.scrollTop >= parent.current.offsetHeight) {
contentBox.current.scrollTop = 0
} else {
contentBox.current.scrollTop++
}
/*判断滚动的距离刚好为一条公告的高度时停掉定时器,
隔1s之后重新启动定时器即可实现公告滚动停留效果 */
if (
contentBox.current.scrollTop % contentBox.current.offsetHeight ===
0
) {
clearInterval(timer)
setTimeout(() => {
timer = setInterval(autoScrollLine, 30)
}, 1000)
}
}
timer = setInterval(autoScrollLine, 30)
}
return () => {
timer = null
}
}, [list])
const handlerClear = () => {
setValue('')
}
return (
<ContentArea value={status}>
<SearchBar
style={{
width: width ? width : '100%',
borderRadius: '6px',
backgroundColor: '#fafafa',
}}
placeholder={list && list.length > 0 ? '' : '搜索菜单'}
value={value}
onChange={handleSearch}
clearOnCancel
onClear={handlerClear}
onFocus={() => {
setStatus(true)
navigate(`${urlSearch}`)
}}
onBlur={() => {
setStatus(false)
}}
/>
<div className="scroll-box" ref={contentBox}>
<div ref={parent}>
{list &&
list.map((item: { menu_name: string }) => (
<span key={item.menu_name}>{item.menu_name}</span>
))}
</div>
<div ref={parentTwo} />
</div>
</ContentArea>
)
}
export default React.memo(RevolvingDoor)
在styled.ts中
import styled from 'styled-components'
const ContentArea = styled.div<{
value: boolean
}>`
.ant-search-input-icon {
color: rgba(0, 0, 0, 0.85);
}
position: relative;
flex: 1;
.scroll-box {
position: absolute;
top: 0px;
left: 30px;
z-index: ${(p: { value: boolean }) => (p.value ? -1 : 2)};
width: 204px;
height: 32px;
overflow: hidden;
line-height: 32px;
pointer-events: none;
div {
margin: 0;
span {
display: block;
color: #bfbfbf;
font-size: 14px;
}
}
}
`
export { ContentArea }
2380

被折叠的 条评论
为什么被折叠?



