中文文档地址
https://better-scroll.github.io/docs/zh-CN/plugins/movable.html
项目中依赖
"@better-scroll/core": "^2.5.0",
"@better-scroll/mouse-wheel": "^2.5.0",
"@better-scroll/observe-dom": "^2.5.0",
"@better-scroll/observe-image": "^2.5.0",
"@better-scroll/pull-down": "^2.5.0",
"@better-scroll/pull-up": "^2.5.0",
下载依赖
cnpm install @better-scroll/core --save
cnpm install @better-scroll/pull-up --save
cnpm install @better-scroll/pull-down --save
cnpm install @better-scroll/mouse-wheel --save
cnpm install @better-scroll/observe-image --save
cnpm install @better-scroll/observe-dom --save
项目封装成组件
import style from './style.module.less';
import { useEffect, useRef, ReactNode, forwardRef, useImperativeHandle } from 'react';
import BScroll from '@better-scroll/core'
import Pullup from '@better-scroll/pull-up'
import PullDown from '@better-scroll/pull-down';
import ObserveDOM from '@better-scroll/observe-dom';
import MouseWheel from '@better-scroll/mouse-wheel'
import ObserveImage from '@better-scroll/observe-image'
BScroll.use(Pullup)
BScroll.use(PullDown)
BScroll.use(ObserveDOM)
BScroll.use(MouseWheel)
BScroll.use(ObserveImage)
interface PropsType {
pullUpOpen?: any,
pullDownOpen?: any,
isPullUpLoad?: boolean,
pullUpCallback?: () => void,
isPullDownLoad?: boolean,
pullDownCallback?: () => void,
list: any,
children: {
list: ReactNode;
};
}
const PullUpPullDownScroll = forwardRef((prop: PropsType, ref) => {
useImperativeHandle( ref,
() => ({
'scrollBottom': () => {
methods.handleScrollBottom();
},
'pullDownFinish': () => {
methods.pullDownFinish();
},
'pullUpFinish': () => {
methods.pullUpFinish();
},
'openPullDown': () => {
methods.openPullDown();
},
'closePullDown': (str: string) => {
methods.closePullDown();
},
'openPullUp': () => {
methods.openPullUp();
},
'closePullUp': () => {
methods.closePullUp();
}
}))
const {pullUpOpen, pullDownOpen, isPullUpLoad, isPullDownLoad, children} = prop;
const bsRef = useRef<any>();
const myBs = useRef<any>();
const methods = {
pullingDownHandler() {
methods.pullDownFinish();
if (isPullDownLoad) return;
prop.pullDownCallback && prop.pullDownCallback();
},
scrollHandler() {
},
pullingUpHandler() {
methods.pullUpFinish();
if (isPullUpLoad) return;
prop.pullUpCallback && prop.pullUpCallback();
},
pullUpFinish() {
let bs = myBs.current;
if (bs) {
bs.finishPullUp();
bs.refresh();
}
methods.handleBsOnchange();
},
pullDownFinish() {
let bs = myBs.current;
if (bs) {
bs.finishPullDown();
bs.refresh();
}
methods.handleBsOnchange();
},
openPullDown() {
const bs = myBs.current;
if (bs) {
bs.openPullDown();
}
},
closePullDown() {
const bs = myBs.current;
if (bs) {
bs.closePullDown();
}
},
openPullUp() {
const bs = myBs.current;
if (bs) {
bs.openPullUp();
}
},
closePullUp() {
const bs = myBs.current;
if (bs) {
bs.closePullUp();
}
},
handleBsOnchange() {
let bs = myBs.current;
if (!bs) return;
if (pullUpOpen) {
bs.off("pullingUp");
bs.once("pullingUp", methods.pullingUpHandler);
}
if (pullDownOpen) {
bs.off("pullingDown");
bs.once("pullingDown", methods.pullingDownHandler);
}
},
handleBsIinit() {
const bs = new BScroll(bsRef.current, {
probeType: 3,
click: true,
scrollY: true,
scrollX: false,
pullUpLoad: pullUpOpen || false,
pullDownRefresh: pullDownOpen || false,
bounceTime: 800,
observeDOM: true,
observeImage: true,
mouseWheel: {
speed: 20,
invert: false,
easeTime: 300
}
})
myBs.current = bs;
methods.handleBsOnchange();
},
handleScrollBottom() {
let bs = myBs.current;
if (!bs) return;
setTimeout(() => {
bs.refresh();
let maxScrollY = bs.maxScrollY;
bs.scrollTo(0, maxScrollY);
}, 200);
}
}
useEffect(() => {
methods.handleBsOnchange();
() => {}
}, [prop]);
useEffect(() => {
methods.handleBsIinit();
return () => {
if (myBs.current) {
myBs.current.destroy();
}
myBs.current = null;
}
},[]);
return (
<div className={`${style.root} 'wrapper'`} ref={bsRef}>
<div>
<div className={`${style.pulldown_wrapper} ${pullDownOpen ? '' : style.display_hide}`}>
{
isPullDownLoad ? <div>加载中...</div> : <div>上拉加载更多</div>
}
</div>
<div>
{
children.list
}
</div>
<div className={`${style.pullup_tips} ${pullUpOpen ? '' : style.display_hide}`}>
{
isPullUpLoad ? <div>加载中...</div> : <div>下拉加载更多</div>
}
</div>
</div>
{/* <div className={style.pulldown_wrapper}>
{
isPullDownLoad ? <div>加载中...</div> : <div>上拉加载更多</div>
}
</div>
<div className='content'>
{
children.list
}
</div>
<div className={style.pullup_tips}>
{
isPullUpLoad ? <div>加载中...</div> : <div>下拉加载更多</div>
}
</div> */}
</div>
)
})
export default PullUpPullDownScroll;
项目中样式
.root{
height: 100%;
position: relative;
overflow: hidden;
box-sizing: border-box;
.pulldown_wrapper{
position: absolute;
width: 100%;
padding: 20px;
box-sizing: border-box;
transform: translateY(-100%) translateZ(0);
text-align: center;
color: #999;
}
.pullup_tips{
position: absolute;
width: 100%;
padding: 20px;
box-sizing: border-box;
transform: translateY(100%) translateZ(0);
text-align: center;
color: #999;
}
.display_hide{
display: none;
}
}
使用
import PullUpPullDownScroll from '@/views/Components/PullUpPullDownScroll';
const [list, setList] = useState([]);
const chatBoxRef = useRef();
const pullDownLoad = useRef(false);
const methods = {
pullDwonCallback() {
}
}
<PullUpPullDownScroll list={list} ref={chatBoxRef}
pullDownOpen={true} isPullDownLoad={pullDownLoad.current} pullDownCallback={() => methods.pullDwonCallback()} >
{{
list: (<>
{
list.map((item: any, index: string) => {
return <div></div>;
})
}
</>)
}}
</PullUpPullDownScroll>