我们经常需要做页面中部分内容可以滚动的功能,例如“猜你喜欢”,内容太多,通常都会超出屏幕,那么此块区域应该可以滚动,但是顶部的自定义导航栏应该不能随着滚动。
这个时候,就可以使用uniapp提供的滚动组件scroll-view。
一、滚动组件 scroll-view
APP-vue和小程序中,请勿在 scroll-view 中使用 map、video 等原生组件。小程序中 scroll-view 中也不要使用 canvas、textarea 原生组件。更新:微信基础库2.4.4起支持了原生组件在scroll-view、swiper、movable-view 中的使用。app-nvue无此限制。
scroll-view 不适合放长列表,有性能问题。长列表滚动和下拉刷新,应该使用原生导航栏搭配页面级的滚动和下拉刷新实现。包括在app-nvue页面,长列表应该使用list而不是scroll-view。
scroll-into-view 的优先级高于 scroll-top。
scroll-view是区域滚动,不会触发页面滚动,无法触发pages.json配置的下拉刷新、页面触底onReachBottomDistance、titleNView的transparent透明渐变。
若要使用下拉刷新,建议使用页面的滚动,而不是 scroll-view。插件市场有前端模拟的基于scroll-view的下拉刷新,但性能不佳。如必需使用前端下拉刷新,推荐使用基于wxs的下拉刷新,性能会比基于js监听方式更高。
scroll-view的滚动条设置,可通过css的-webkit-scrollbar自定义,包括隐藏滚动条(app-nvue无此css)
二、滚动组件使用示例
1、主要代码示例
1)将需要滚动的内容放入scroll-view
组件中,并设置竖向滚动scroll-y
2)设置样式,页面高度 100%,设置flex布局,让scroll-view撑满剩余空间
page{
background-color: #fefefe;
display: flex;
height: 100%;
flex-direction: column;
flex-flow: column;
}
.scroll-view {
flex: 1;
overflow: hidden;
}
3)添加滚动触底事件 @scrolltolower,并设置ts类型UniHelper.ScrollViewOnScrolltolowerEvent
const onScrolltolower =(e : UniHelper.ScrollViewOnScrolltolowerEvent)=>{
console.log('到底部了',e);
}
4)添加猜你喜欢测试组件my-guess
.caption {
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
.text {
display: flex;
justify-content: center;
align-items: center;
}
}
.guess {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background-color: #efefef;
margin: 5rpx;
.guess-item {
width: 334rpx;
padding: 10rpx;
margin: 10rpx;
overflow: hidden;
background-color: #fff;
border-radius: 10rpx;
display: flex;
flex-direction: column;
align-items: center;
.image {
width: 304rpx;
height: 260rpx;
}
.name {
height: 75rpx;
margin: 10rpx 0;
font-size: 26rpx;
color: #262626;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
display: -webkit-box;
}
.small {
width: 100rpx;
height: 100rpx;
}
.text {
font-size: 26rpx;
color: #666;
}
}
}
3、扩展:使用ref属性调用子组件my-guess
的方法加载更多数据
1)在index.vue中定义ref
import type { MyGuessInstance } from '@/components/components';
import { ref } from 'vue'
const guessRef = ref<MyGuessInstance>()
const onScrolltolower =(e : UniHelper.ScrollViewOnScrolltolowerEvent)=>{
console.log('到底部了');
guessRef.value?.getMore()
}
2)定义组件实例类型
// src\components\components.d.ts
export type MyGuessInstance = InstanceType
3)定义远程接口事件,以及对象类型
// src\types\global.d.ts
export type PageResult={
/**列表数据 */
items:T[]
/**总条数 */
coounts:number
/**当前页数 */
page:number
/**总页数 */
pages:number
/**每页条数 */
pageSize:number
}
// src\types\home.d.ts
export type GuessItem = {
/**商品描述 */
desc: string
id: string
/** 商品折扣 */
discount: number
/** 商品已下单数量 */
orderNumber: number
/** 商品名称 */
name: string
/** 商品图片 */
picture: string
/** 商品价格 */
price: number
}
// src\services\home.ts
export const getHomeGuessAPI = () => {
return http>({
method: 'GET',
url: ""
})
}
4)组件my-guess暴露方法getMore
import { getHomeGuessAPI } from '@/services/home';
import type { GuessItem } from '@/types/home';
import { ref } from 'vue';
const guessList = ref<GuessItem[]>([])
const getNextPageGuess=async ()=>{
console.log('加载更多....');
const res = await getHomeGuessAPI()
guessList.value = res.data.items
}
// 暴露方法
defineExpose({
getMore:getNextPageGuess
})