【uniapp】小程序开发8:滚动组件scroll-view

我们经常需要做页面中部分内容可以滚动的功能,例如“猜你喜欢”,内容太多,通常都会超出屏幕,那么此块区域应该可以滚动,但是顶部的自定义导航栏应该不能随着滚动。
这个时候,就可以使用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

<template>
  <my-navbar class="my-navbar" :title="'我是首页导航'"/>
  <scroll-view @scrolltolower="onScrolltolower" class="scroll-view" scroll-y>
    
    <my-swipper/>
    
    <my-category-pannel/>
    
    <my-guess/>
  scroll-view>
template>

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


<template>
    <view>
        <view class="caption">
            <text class="text">猜你喜欢text>
        view>
        <view class="guess">
            <navigator open-type="navigate" class="guess-item" v-for="item in 10" :key="item">
                <image src="/static/phone.jpg" class="image" mode="aspectFill" />
                <view class="name">华为Mate 60 pro+ 16G 512G 超级待机版本view>
                <view class="price">
                    <text class="small">text>
                    <text>6999.00text>
                view>
            navigator>
        view>
    view>
template>
  
<script lang="ts" setup>
script>
<style scoped lang="scss">
.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;
        }
    }
}style>

2、效果预览

上下滚动时,顶部的自定义导航栏始终不会改变位置!

【uniapp】小程序开发8:滚动组件scroll-view_第1张图片

3、扩展:使用ref属性调用子组件my-guess的方法加载更多数据

1)在index.vue中定义ref

<template>
  <my-navbar :title="'我是首页导航'"/>
  <scroll-view @scrolltolower="onScrolltolower" class="scroll-view" scroll-y>
    
    
    <my-guess ref="guessRef"/>
  scroll-view>
template>

<script setup lang="ts">

import type { MyGuessInstance } from '@/components/components';
import { ref } from 'vue'

const guessRef = ref<MyGuessInstance>()
const onScrolltolower =(e : UniHelper.ScrollViewOnScrolltolowerEvent)=>{
  console.log('到底部了');
  guessRef.value?.getMore()
}
script>

2)定义组件实例类型

// src\components\components.d.ts
export type MyGuessInstance = InstanceType<typeof MyGuess>

3)定义远程接口事件,以及对象类型

// src\types\global.d.ts
export type PageResult<T>={
    /**列表数据 */
    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<PageResult<GuessItem>>({
        method: 'GET',
        url: ""
    })
}

4)组件my-guess暴露方法getMore

<script lang="ts" setup>
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
})
</script>

你可能感兴趣的:(前端,uniapp开发小程序,uni-app,小程序)