自学内容网 自学内容网

uniapp内置组件scroll-view案例解析

参考资料

文档地址:https://uniapp.dcloud.net.cn/component/scroll-view.html

官方给的完整代码

<script>
export default {
data() {
return {
scrollTop: 0,
old: {
scrollTop: 0
}
}
},
methods: {
upper: function(e) {
console.log(e)
},
lower: function(e) {
console.log(e)
},
scroll: function(e) {
console.log(e)
this.old.scrollTop = e.detail.scrollTop
},
goTop: function(e) {
// 解决view层不同步的问题
this.scrollTop = this.old.scrollTop
this.$nextTick(function() {
this.scrollTop = 0
});
uni.showToast({
icon: "none",
title: "纵向滚动 scrollTop 值已被修改为 0"
})
}
}
}
</script>

<template>
<view>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
Vertical Scroll
<text>\n纵向滚动</text>
</view>
<view>
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scrolltoupper="upper"
@scrolltolower="lower" @scroll="scroll">
<view id="demo1" class="scroll-view-item uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item uni-bg-blue">C</view>
</scroll-view>
</view>
<view @tap="goTop" class="uni-link uni-center uni-common-mt">
点击这里返回顶部
</view>

<view class="uni-title uni-common-mt">
Horizontal Scroll
<text>\n横向滚动</text>
</view>
<view>
<scroll-view class="scroll-view_H" scroll-x="true" @scroll="scroll" scroll-left="120">
<view id="demo1" class="scroll-view-item_H uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item_H uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item_H uni-bg-blue">C</view>
</scroll-view>
</view>
<view class="uni-common-pb"></view>
</view>
</view>
</template>

<style>
.scroll-Y {
height: 300rpx;
}
.scroll-view_H {
white-space: nowrap;
width: 100%;
}
.scroll-view-item {
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}
.scroll-view-item_H {
display: inline-block;
width: 100%;
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}
</style>

此时的渲染效果

在这里插入图片描述

小目标

这个案例代码比较复杂,需要拆解来看。拆分为垂直滚动和横向滚动两个小案例。

之前代码是基于vue2写的,需要改造为vue3的代码。

先把代码改为vue3的setup语法

之前的代码:

export default {
data() {
return {
scrollTop: 0,
old: {
scrollTop: 0
}
}
},
methods: {
upper: function(e) {
console.log(e)
},
lower: function(e) {
console.log(e)
},
scroll: function(e) {
console.log(e)
this.old.scrollTop = e.detail.scrollTop
},
goTop: function(e) {
// 解决view层不同步的问题
this.scrollTop = this.old.scrollTop
this.$nextTick(function() {
this.scrollTop = 0
});
uni.showToast({
icon: "none",
title: "纵向滚动 scrollTop 值已被修改为 0"
})
}
}
}

改造后的代码:

import {
ref
} from 'vue';
const scrollTop = ref(0)
const old = ref({
scrollTop: 0
})

function upper(e) {
console.log(e)
}

function lower(e) {
console.log(e)
}

function scroll(e) {
console.log(e)
old.value.scrollTop = e.detail.scrollTop
}

function goTop(e) {
// 解决view层不同步的问题
scrollTop.value = old.value.scrollTop
nextTick(function() {
scrollTop.value = 0
});
uni.showToast({
icon: "none",
title: "纵向滚动 scrollTop 值已被修改为 0"
})
}

垂直滚动案例

接下来拆分案例,先记录一下此时的完整代码,避免改乱了无法恢复。

<script setup>
import {
ref
} from 'vue';
const scrollTop = ref(0)
const old = ref({
scrollTop: 0
})

function upper(e) {
console.log(e)
}

function lower(e) {
console.log(e)
}

function scroll(e) {
console.log(e)
old.value.scrollTop = e.detail.scrollTop
}

function goTop(e) {
// 解决view层不同步的问题
scrollTop.value = old.value.scrollTop
nextTick(function() {
scrollTop.value = 0
});
uni.showToast({
icon: "none",
title: "纵向滚动 scrollTop 值已被修改为 0"
})
}
</script>

<template>
<view>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
Vertical Scroll
<text>\n纵向滚动</text>
</view>
<view>
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scrolltoupper="upper"
@scrolltolower="lower" @scroll="scroll">
<view id="demo1" class="scroll-view-item uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item uni-bg-blue">C</view>
</scroll-view>
</view>
<view @tap="goTop" class="uni-link uni-center uni-common-mt">
点击这里返回顶部
</view>

<view class="uni-title uni-common-mt">
Horizontal Scroll
<text>\n横向滚动</text>
</view>
<view>
<scroll-view class="scroll-view_H" scroll-x="true" @scroll="scroll" scroll-left="120">
<view id="demo1" class="scroll-view-item_H uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item_H uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item_H uni-bg-blue">C</view>
</scroll-view>
</view>
<view class="uni-common-pb"></view>
</view>
</view>
</template>

<style>
.scroll-Y {
height: 300rpx;
}

.scroll-view_H {
white-space: nowrap;
width: 100%;
}

.scroll-view-item {
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}

.scroll-view-item_H {
display: inline-block;
width: 100%;
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}
</style>

接着移除水平滚动相关的代码,移除后得到的代码如下:

<template>
<view>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
Vertical Scroll
<text>\n纵向滚动</text>
</view>
<view>
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scrolltoupper="upper"
@scrolltolower="lower" @scroll="scroll">
<view id="demo1" class="scroll-view-item uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item uni-bg-blue">C</view>
</scroll-view>
</view>
<view @tap="goTop" class="uni-link uni-center uni-common-mt">
点击这里返回顶部
</view>
<view class="uni-common-pb"></view>
</view>
</view>
</template>

这里发现了另一个一个比较细节的知识点,就是回到顶部的功能。先分析回到顶部的功能。

回到顶部的功能

HTML代码如下:

<view @tap="goTop" class="uni-link uni-center uni-common-mt">
点击这里返回顶部
</view>

js代码如下:

async function goTop(e) {
// 解决view层不同步的问题
scrollTop.value = old.value.scrollTop
await nextTick(function() {
scrollTop.value = 0
});
uni.showToast({
icon: "none",
title: "纵向滚动 scrollTop 值已被修改为 0"
})
}

注意,这个函数是异步的,因为nextTick是一个异步方法,需要使用await。
这个方法是从vue引入的:

import {
ref,
nextTick,
} from 'vue';

回到顶部的功能是如何生效的?

经过测试, 我现在垂直滚动到了C:
在这里插入图片描述

然后我点击返回顶部:
在这里插入图片描述

可以发现,垂直滚动的位置又回到了A。

不过我们在学习的时候,应该先学习垂直滚动是如何实现的,再学习如何实现回到顶部的功能。

继续分析如何实现垂直滚动

核心的HTML代码如下:

<scroll-view 
:scroll-top="scrollTop" 
scroll-y="true" 
class="scroll-Y" 
@scrolltoupper="upper"
@scrolltolower="lower" @scroll="scroll">
<view id="demo1" class="scroll-view-item uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item uni-bg-blue">C</view>
</scroll-view>

代码分析:

  • 首先组件使用了scroll-view
  • 动态绑定了一个值,这个值记录的是滚动的顶部的位置 :scroll-top="scrollTop" ,这个值的初始值为0,在js中定义如下 const scrollTop = ref(0)
  • 这个属性 scroll-y="true" 是最关键的,将滚动方向设置成了垂直方向
  • 通过 class="scroll-Y" 样式,给容器设置了一个固定高度 height: 300rpx;,因为父盒子的高度是固定的,而内容的高度超过了父元素的限制,所以就出现了滚动的效果
  • @scrolltoupper="upper" 经过官方文档的解释,滚动到顶部/左边,会触发 scrolltoupper 事件,因为我们是垂直滚动的,不会滚动到左边,所以,当我们滚动到最顶部的时候,会触发这个事件
  • @scrolltolower="lower" 这个就是滚动到最底部的时候触发的事件了
  • @scroll="scroll" 这个是只要滚动,就会产生的事件
  • <view id="demo1" class="scroll-view-item uni-bg-red">A</view> 内容就比较简单了,核心的地方在于每个内容item的高度都和父元素的高度一样 height: 300rpx;

所以得出的结论如下:

  • 使用 scroll-view 能够得到一个滚动的容器
  • 设置 scroll-y="true" 可以实现垂直滚动
  • 将父元素的高度和每个子元素的高度都设置为相同的高度,会产生类似于整个屏幕滚动的效果

如何实现水平滚动

核心代码如下:

<scroll-view 
class="scroll-view_H" 
scroll-x="true" 
@scroll="scroll" 
scroll-left="120">
<view id="demo1" class="scroll-view-item_H uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item_H uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item_H uni-bg-blue">C</view>
</scroll-view>

可以发现,和水平滚动类似,只不过通过 scroll-x="true" 设置了水平滚动。

scroll-left="120" 经过官方文档解释,是在设置滚动条的位置。

实现垂直滚动的完整代码

<script setup>
import {
ref,
nextTick,
} from 'vue';
const scrollTop = ref(0)
const old = ref({
scrollTop: 0
})

function upper(e) {
console.log(e)
}

function lower(e) {
console.log(e)
}

function scroll(e) {
console.log(e)
old.value.scrollTop = e.detail.scrollTop
}

async function goTop(e) {
// 解决view层不同步的问题
scrollTop.value = old.value.scrollTop
await nextTick(function() {
scrollTop.value = 0
});
uni.showToast({
icon: "none",
title: "纵向滚动 scrollTop 值已被修改为 0"
})
}
</script>

<template>
<view>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
Vertical Scroll
<text>\n纵向滚动</text>
</view>
<view>
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scrolltoupper="upper"
@scrolltolower="lower" @scroll="scroll">
<view id="demo1" class="scroll-view-item uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item uni-bg-blue">C</view>
</scroll-view>
</view>
<view @tap="goTop" class="uni-link uni-center uni-common-mt">
点击这里返回顶部
</view>
<view class="uni-common-pb"></view>
</view>
</view>
</template>

<style>
.scroll-Y {
height: 300rpx;
}

.scroll-view_H {
white-space: nowrap;
width: 100%;
}

.scroll-view-item {
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}

.scroll-view-item_H {
display: inline-block;
width: 100%;
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}
</style>

设置水平滚动的完整代码

<script setup>
import {
ref,
nextTick,
} from 'vue';
const scrollTop = ref(0)
const old = ref({
scrollTop: 0
})

function upper(e) {
console.log(e)
}

function lower(e) {
console.log(e)
}

function scroll(e) {
console.log(e)
old.value.scrollTop = e.detail.scrollTop
}

async function goTop(e) {
// 解决view层不同步的问题
scrollTop.value = old.value.scrollTop
await nextTick(function() {
scrollTop.value = 0
});
uni.showToast({
icon: "none",
title: "纵向滚动 scrollTop 值已被修改为 0"
})
}
</script>

<template>
<view>
<scroll-view 
class="scroll-view_H" 
scroll-x="true" 
@scroll="scroll" 
scroll-left="120">
<view id="demo1" class="scroll-view-item_H uni-bg-red">A</view>
<view id="demo2" class="scroll-view-item_H uni-bg-green">B</view>
<view id="demo3" class="scroll-view-item_H uni-bg-blue">C</view>
</scroll-view>
</view>
</template>

<style>
.scroll-Y {
height: 300rpx;
}

.scroll-view_H {
white-space: nowrap;
width: 100%;
}

.scroll-view-item {
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}

.scroll-view-item_H {
display: inline-block;
width: 100%;
height: 300rpx;
line-height: 300rpx;
text-align: center;
font-size: 36rpx;
}
</style>

原文地址:https://blog.csdn.net/qq_37703224/article/details/140396052

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!