uniapp中scroll-view,uniapp scrollview滚动到指定位置
UNI-APP开发(仿饿)开发课程:进入学习
最近做了一个微信小程序的直播模块。模块中的聊天室功能以滚动视图一维数组的形式显示,没有优化,导致用户体验差。
一、优化前模拟聊天室。
可见蛋疼~
但是优化还是要优化,没有优化是不行的。但是在开始之前,我觉得有必要把优化步骤拆分成以下两点?
1. 不再使用scroll-into-view设置锚点
因为旧版本是以滚动视图一维数组的形式实现的,所以页面总是显示数据添加后的最后一条信息,而不是加载前的最后一条信息。所以之前的开发者在数据加载后使用了scroll-into-view属性作为返回锚点,但是锚点的切换和数据加载并没有同步发生,导致了反弹的现象。
2. 大量数据的处理
因为是聊天室功能,不可避免的要加载大量的用户对话、图片等内容,又因为scroll-view本身就不适合加载大量的数据(太复杂想不出别的办法),所以要在数据加载和显示部分下功夫。
3. 附加功能处理
本来聊天室还是有回底层的功能的,所以优化后不能忽略原来的功能。
好了,走吧~
1、倒置scroll-view
为什么反转滚动视图?从上面第一点可以看出,如果数据需要按正序插入,必然会导致数据加载后无法显示的情况。但是,如果您想解决这种情况,您需要使用scroll-into-view属性。如果你需要彻底解决这个问题,你需要从问题的根源——滚动视图入手。
是先修改前的代码吗?
这是实时图片/视图
滚动视图
滚动
:scroll-y=true
:scroll-into-view= scrollIntoView
@scrolltoupper=upper
视角
:id=item.index
:style={
backgroundColor: item.color,
高度:“200rpx”,
行高:“200rpx”,
文本对齐:“居中”,
}
v-for= scroll data中的项目
:key=item.index
{{ item.data }}
/查看
/scroll-view const scrollIntoView=ref( index 1 );
const upper=()={
设lastNum=scrollData.value[0]。数据;
设new arr=[];
for(设索引=1;指数=10;索引){
newArr.push({
color: getRandomColor(),
数据:lastNum指数,
index: `index${lastNum index} `,
});
}
scrollData.value.unshift(.new arr . reverse());
//这里可以用nextTick替换,结果是一样的,但是为了更明显的反弹效果我用了timer。
setTimeout(()={
scrollintoview . value=` index $ { last num } `;
console.log(scrollIntoView:,scrollIntoView . value);
}, 100);
};
const getRandomColor=()={
返回 # Math.random()。toString(16)。substr(2,6);
};所以让我们先试着反转滚动视图,它不起作用。
首先,我们需要在scroll-view上设置一个transform:rotate(180deg)属性,然后在内部子元素上设置相同的属性。不要忘记反转存储数据的数组。最重要的是,去掉scroll-view上的scroll-into-view属性,就会得到这个效果?
还有,这个时候滚动条的位置在左边。如有必要,可以使用CSS属性将其移除,或者自己模拟。下面是移除滚动条的CSS样式?
:-WebKit-滚动条{
显示:无;
宽度:0;
高度:0;
颜色:透明;
}这里只是第一步。下一步是如何下拉和加载数据。
这时候我们的卷轴视图就是一个倒置的状态,也就是说上面是下面,下面是上面(有绕口令)。因此,之前使用的滚动顶部触摸方式不得不由scrolltolower触摸方式代替,实现“下拉加载”。
下面是现在的聊天室,看起来好多了。
2、大量数据的处理
处理完回弹问题后,就需要考虑如何处理大量数据。由于uni-app官方也在文档中提到scroll-view加载大批量数据的时候性能较差,但无奈手头上也没有别的办法,只能死马当活马医了
我第一个想到的是一个非常经典的虚拟列表,但是我之前看的很多关于虚拟列表的文章都是在web端实现的。貌似不是小程序领域常用的方法,不过还好我在微信小程序里找到了如何实现虚拟列表的资料。详情请查看这篇文章。微信小程序虚拟列表
如果你说OK,就去做,那么第一步就是要明确实现虚链表需要什么样的数据结构。其实虚列表简单来说就是当某个模块的数据超出可见范围时,将其隐藏。那么如何把数据分成多个模块呢?答案是二维数组。
首先存储当前页码(默认为0),当触发下拉加载动作时,页码为1,然后将当前页码作为下标存储在数组中。
const currentShowPage=ref(0)
const upper=()={
let len=scroll data . value[current show page . value]。长度-1;
设lastNum=scroll data . value[current show page . value][len]。数据;
设new arr=[];
currentshowpage . value=1;
for(设索引=1;指数=10;索引){
newArr.push({
color: getRandomColor(),
数据:lastNum指数,
index: `index${lastNum index} `,
});
}
scroll data . value[currentshowpage . value]=new arr;
};当然,别忘了你还需要在页面中以二维数组的形式循环数据。
scroll-view style= transform:rotate(180 deg):scroll-y= true @ scroll tolower= upper
在scrollData中查看v-for=(data,index):key= index
视角
style=变换:旋转(180度)
:style={
backgroundColor: item.color,
高度:“200rpx”,
行高:“200rpx”,
文本对齐:“居中”,
}
v-for=数据中的项目
:key=item.index
{{ item.data }}
/查看
/查看
/scroll-view
数据结构的问题解决了,那么接下来就是如何判断数据模块是否超出可视范围。
首先我们要知道每个数据模块的高度。其实很简单。我们只需要为每个模块定义一个id,然后数据显示后根据id得到那个模块的节点信息,并按顺序存储在一个数组中。
const pagesHeight=[]
onReady(()={
setPageHeight()
})
const upper=()={
.
nextTick(()={
//每次获得新数据时调用它
setPageHeight();
});
};
const setPageHeight=()={
let query=uni . createselectquery();
询问。选择(` #item-${currentShowPage.value} `)。boundingClientRect(res={
pagesHeight[currentshowpage . value]=RES RES . height;
})。exec();
};好了,现在我们知道了每个模块的高度,然后就是监控模块和可视窗口的交叉范围。这里有两种方法,一种是JS获取可见窗口的高度并计算模块scrollTop的差值,另一种是使用小程序的createIntersectionObserver方法让程序自行监控相交区域。
我这里展示的是第二种方法。如果对第一种方法感兴趣,可以看看我在第二章开头推荐的文章《微信小程序虚拟列表》。
createIntersectionObserver方法的使用其实很简单。我们只需要传入可见窗口的id和要监控的模块的id。详见官方文件。
onReady(()={
.
observer(currentshowpage . value);
});
const upper=()={
.
nextTick(()={
//每次获得新数据时调用它
观察者();
});
};
//允许渲染的数组下标,需要设置默认值。
const visiblePagesList=ref([-1,0,1])
const observer=pageNum={
常量观察视图=wx。createIntersectionObserver()。relativeTo(#scroll ,{ top: 0,bottom:0 });
observe view . observe(` # item-$ { pageNum } `,res={
if(RES . intersect ratio 0)visible pages list . value=[pageNum-1,pageNum,pageNum 1];
});
};最后是判断该模块是否允许在页面中呈现(即是否存储在visiblePagesList数组中)。在这里,很简单,只需在页面中写一个方法调用即可。
scroll-view id= scroll class= scroll :scroll-y= true @ scroll tolower= upper
scrollData中的视图v-for=(data,index :key= index :id= item- index
模板v-if=includePage(index)
视角
class=滚动项目
:style={
.
}
v-for=数据中的项目
:key=item.index
{{ item.data }}
/查看
/模板
view v-else:style= { height:pagesHeight[index]} /view
/查看
/scroll-view const include page=index={
返回visiblepageslist。价值。(index)-1的索引;
};来看看效果如何
额.似乎没有太大区别,那我们看看页面结构到底也没有将可视区域外的内容切换为空白视角
成功!
3、功能调整
聊天室原本还有回底功能等,也不能忘了加上
这个部分就比较简单了,只需要直接使用滚动视图的滚动顶部属性,然后通过在卷起回调中动态记载滚动顶部的值即可
下面是部分代码
滚动视图
id=scroll
滚动
:scroll-y=true
:scroll-top=currentTop
@scroll=handle_scroll
@scrolltolower=upper
.
/滚动视图
view v-show= showGoBottom class= go-back-BTN @ click= handle _ go bottom 回底/viewlet滚动顶部;
const current top=ref(0);
const showGoBottom=ref(false);
常量handle_scroll=throttle(event={
scroll top=event[0]。细节。滚动顶部;
if (scrollTop 300) {
showGoBottom.value=true
}
}, 100);
const handle_goBottom=()={
当前顶部。value=滚动顶部;
nextTick(()={
当前顶部。值=0;
});
showGoBottom.value=false
};大功告成~
最后附上演示仓库
https://gitee.com/huang-qihao123/virtual-list-demo
推荐: 《uniapp教程》 以上就是聊聊uniapp的滚动视图下拉加载的详细内容,更多请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。