最近用到了下拉刷新,所以尝试了下使用betterScroll2.5,封装了一个插槽组件,也是第一次使用react,基于当时的知识写的,反正能用,如果有更好的方法封装欢迎同学给予帮助;
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
// pullup 插件为 BetterScroll 扩展上拉加载的能力
cnpm install @better-scroll/pull-up --save
// pulldown 插件为 BetterScroll 扩展下拉刷新的能力
cnpm install @better-scroll/pull-down --save
// mouseWheel 扩展 BetterScroll 鼠标滚轮的能力
cnpm install @better-scroll/mouse-wheel --save
// 检测图片加载重新计算
cnpm install @better-scroll/observe-image --save
// 当这些 DOM 元素发生变化时,将会触发 scroll 的 refresh 方法
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, // pullUp回调
isPullDownLoad?: boolean, // 加载中
pullDownCallback?: () => void, // pullDown回调
list: any, // 当前滚动list,为了数据变化重新指定,绑定触发的事件
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>();
// 初始化bscroll
const methods = {
pullingDownHandler() {
methods.pullDownFinish();
if (isPullDownLoad) return;
prop.pullDownCallback && prop.pullDownCallback();
},
scrollHandler() {
},
pullingUpHandler() {
methods.pullUpFinish();
if (isPullUpLoad) return;
prop.pullUpCallback && prop.pullUpCallback();
},
pullUpFinish() { // 重置pullUp状态
let bs = myBs.current;
if (bs) {
bs.finishPullUp();
bs.refresh();
}
methods.handleBsOnchange();
},
pullDownFinish() { // 重置pullDown状态
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, // 开启 observe-dom 插件
observeImage: true, // 开启 observe-image 插件
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(() => {
// 初始化scroll
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>
{/*
{
isPullDownLoad ? 加载中... : 上拉加载更多
}
{
children.list
}
{
isPullUpLoad ? 加载中... : 下拉加载更多
}
*/}
</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([]); // 当前list
/*
绑定ref可以调用相关方法
举例:chatBoxRef.current.scrollBottom(); // 滚动到底部
*/
const chatBoxRef = useRef();
const pullDownLoad = useRef(false); // 是否再ajax
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>