这个在手机上卡的要死,最好还是使用点击的那种
uniapp实现页面滑动
整体代码
<template>
<view :style="{height:comHeight-swiperheight-padding+'px'}">
<scoll :list="scoll" @getIndex="getIndex1" :activeIndex.sync="activeIndex" :index="index" class="padding"
ref="scoll" />
<swiper :style="{height:comHeight-swiperheight-padding+'px'}" :current="activeIndex" @change="changeIndex"
:disable-touch="touch" :duration="durations">
<block v-for="(item,index) in scoll.length" :key="index">
<swiper-item>
<view class="swiper-item padding" :style="{'padding-bottom':padding+10+'px'}" style="height: 100%;">
<scroll-view scroll-y="true" style="height: 100%;" @scrolltolower="getTaskList" scroll-anchoring
@refresherrefresh="refresherrefresh" @refresherrestore="refresherrestore"
@refresherabort="refresherabort" :refresher-triggered="refresherTriggered"
:refresher-threshold="45" :refresher-enabled="true" refresher-background="#f9f9f9">
<hotList :list="taskList[index].data" ref="hotList" v-if="taskList[index].hackReset" />
<view class="u-loadding" v-show="loadding">
<u-loading mode="flower" size="40" />
</view>
<u-divider v-if="(taskList[activeIndex].page-1)* limit >= taskList[activeIndex].totalCount">
没有更多了</u-divider>
</scroll-view>
</view>
</swiper-item>
</block>
</swiper>
</view>
</template>
<script>
import scoll from '@/components/scoll/scoll.vue';
import hotList from '@/components/hotList/hotList.vue';
export default {
components: {
hotList,
scoll,
},
props: {
isRefresh: Boolean,
comHeight: Number,
index: Boolean,
padding: Number
},
data() {
return {
refresherTriggered: false,
_refresherTriggered: false,
refresher: false,
refresh: false,
triggered: false, //是否开启下拉刷新
more: false, //没有更多了
label_id: 0,
durations: 500,
touch: false,
touchStart: 0,
touchMove: 0,
loadding: false,
scoll: [{
id: 0,
name: '全部',
type: false
}],
swiperheight: 0,
taskList: [{
data: [],
page: 1,
ctime: '',
totalCount: 1,
hackReset: true
}], //数据列表
limit: 9, //每页请求的数量
activeIndex: 0
}
},
watch: {
isRefresh(res) {
if (res) {
this.refresherrefresh()
}
}
},
mounted() {
let query = uni.createSelectorQuery().in(this)
query.select('.padding').boundingClientRect(res => {
this.swiperheight = res.height
}).exec()
this.getCard()
this.getTaskList()
},
methods: {
// 自定义下拉刷新被触发
refresherrefresh() {
let _this = this;
if (_this._refresherTriggered) {
return;
}
_this._refresherTriggered = true;
//界面下拉触发,triggered可能不是true,要设为true
if (!_this.refresherTriggered) {
_this.refresherTriggered = true;
}
this.loadStoreData();
},
// 自定义下拉刷新被复位
refresherrestore() {
let _this = this;
_this.refresherTriggered = false;
_this._refresherTriggered = false;
},
// 自定义下拉刷新被中止
refresherabort() {
let _this = this;
_this.refresherTriggered = false;
_this._refresherTriggered = false;
},
loadStoreData() {
let _this = this;
_this.taskList[_this.activeIndex] = {
data: [],
page: 1,
ctime: '',
totalCount: 1,
hackReset: false
}
setTimeout(res => {
_this.getTaskList("Refresh")
}, 500)
},
// 根据点击跳转相应的标签
changeSchool() {
let changeIndex = 0
let indexID = uni.getStorageSync('type_id') || 0
this.scoll.forEach((res, index) => {
if (res.id == indexID) {
changeIndex = index
}
})
uni.removeStorageSync('type_id')
this.getIndex1(changeIndex, changeIndex > 0 ? indexID : 0)
},
// 获取列表
getCard() {
this.$request.register("communication/getTypeList", {
type: 0,
}).then((res) => {
let typeList = [];
for (let i = 0; i < res.length; i++) {
this.scoll.push({
id: res[i].id,
name: res[i].name,
type: false,
});
this.taskList[i + 1] = {
data: [],
page: 1,
ctime: '',
totalCount: 1,
hackReset: true
}
}
setTimeout(res => {
this.changeSchool()
}, 500)
})
.catch((res) => {
uni.showToast({
title: res,
icon: "none",
});
});
},
getTaskList() {
let taskList = this.taskList[this.activeIndex]
if (this.loadding || (taskList.page - 1) * this.limit >= taskList.totalCount) {
return
}
this.loadding = true
this.$request.register('task/list', {
page: taskList.page,
limit: this.limit,
query: {
label_id: this.label_id,
ctime: taskList.ctime
},
}).then(res => {
if (this.refresherTriggered) {
this.refresherTriggered = false; //触发onRestore,并关闭刷新图标
this._refresherTriggered = false;
uni.showToast({
title: "刷新成功",
icon: "none"
})
}
taskList.hackReset = true
if (taskList.page === 1) {
taskList.ctime = res.ctime
}
taskList.page++;
taskList.totalCount = res.totalCount
res.data.forEach(item => {
taskList.data.push({
...item
})
});
this.loadding = false
}).catch(res => {
this.loadding = false
uni.showToast({
title: res,
icon: 'none'
})
})
},
// 滑动切换
changeIndex(res) {
this.label_id = this.$refs.scoll.changeIndex(res.detail.current)
this.activeIndex = res.detail.current
if (this.taskList[this.activeIndex].data.length == 0) {
this.getTaskList("Refresh")
}
this.$refs.scoll.scollChange(res.detail.current)
},
// 点击导航切换
getIndex1(res, item) {
this.label_id = item
this.durations = 0
this.activeIndex = res
setTimeout(res => {
this.durations = 500
}, 30)
}
}
}
</script>
<style scoped>
.swiper-item {
height: 100%;
}
.padding {
padding: 0 30rpx;
}
</style>
菜单部分代码
<template>
<view >
<scroll-view scroll-x class="nav-tab-wrap" :throttle="false" @scroll="scrollEvent" scroll-with-animation
:scroll-left="scrollLeft" >
<view class="nav-tab">
<block v-for="(item,index) in list" :key="index">
<view class="nav-tab-item" :style="index==list.length-1?'margin-right:0;':''" :class="{'active':currentIndex==index}" @tap="changeTab(index,item.id)">{{item.name}}
</view>
</block>
<view class="underline" :style="'left:'+ left +'px;width:'+ width +'px;'"></view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
props: {
list: Array,
activeIndex: Number //当前选中的下标
},
data() {
return {
withs:false,
currentIndex: 0, //当前选中的索引值
left: 0, //滑动条左边距离
width: 0, //滑动条宽度
scrollX: 0, //滚动条的位置
space: uni.upx2px(-35), //滑动条和item的左右间距
scrollLeft: 0, //滚动条到左边的距离
contentScroll: 0 //滚动条的宽度
}
},
methods: {
changeTab(num) {
let that = this;
that.currentIndex = num;
this.scollChange(num)
this.$emit('getIndex', num,that.list[num].id)
},
//用来监听菜单栏下面的横条,还有让菜单栏选中的部分居中
scollChange(num){
let that = this;
let selectorQuery = uni.createSelectorQuery().in(that);
selectorQuery.selectAll('.nav-tab-item').boundingClientRect(function(data) {
// data 为当前选中tab的节点信息
num==0?that.left=0:that.left = data[num].left + that.scrollX + that.space;
that.width = data[num].width;
}).exec();
// 获取滚动条的宽度
selectorQuery.select('.nav-tab-wrap').boundingClientRect(data => {
this.contentScroll = data.width
}).exec()
this.scrollLeft =parseInt(this.left) - parseInt(this.contentScroll / 2) + parseInt(that.width / 2)
setTimeout(res=>{
this.scrollLeft =parseInt(this.left) - parseInt(this.contentScroll / 2) + parseInt(that.width / 2) //再次刷新下横向滚动条。防止出现手机端不居中的情况
},100)
},
//父组件滑动切换时返回当前菜单的id,用来父组件请求数据
changeIndex(index){
this.currentIndex = index;
return this.list[index].id
},
scrollEvent(e) {
this.scrollX = e.detail.scrollLeft;
}
}
}
</script>
<style lang="less">
.active{border-bottom: 1px solid #FF6100;}
scroll-view ::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
.nav-tab-wrap {
max-width: 100%;
white-space: nowrap;
.nav-tab {
position: relative;
.nav-tab-item {
margin-right: 60rpx;
line-height: 80rpx;
display: inline-block;
color: #989898;
font-size: 28rpx;
&.active {
color: #FF6100;
}
}
.underline {
position: absolute;
height: 5rpx;
background-color: #FF6100;
bottom: 0;
transition: 0.2s;
}
}
}
</style>
列表部分代码
<template>
<view>
<view class="list">
<view class="list-list " v-for="(item,index) in Hotlist" :key="index" @tap="jump(item.id)">
<view class="list-cloumn list-cloumn-margin">
<view class="list-title ">
{{item.title}}
</view>
<view class="list-price " v-if="$request.money">
<text>¥</text>{{item.price}}
</view>
</view>
<view class="list-cloumn-second list-cloumn-margin">
<view class="list-menu" v-for="(res,index) in item.label" :key="index">
{{res.name}}
</view>
</view>
<view class="list-cloumn-second list-describes list-cloumn-margin">
{{item.describes}}
</view>
<view class="list-cloumn">
<view>
<view class="list-address">
<image src="../../static/many/map1.png" mode=""></image>
<!-- {{item.address.city}} -->
<view class="list-address-text">
<text v-if="JSON.stringify(item.address)!=='[]'"> {{item.address.district}}</text>
<text v-else>线上任务</text>
</view>
</view>
</view>
<view class="list-number">
<view class="list-endTimer " style="margin-right: 36upx;" v-if="item.end_time">
{{item.end_time}}前
</view>
<view class="list-endTimer list-count"
:class="item.view_count==item.max_number?'list-endColor':''">
抢单 {{item.count}}/{{item.max_number}}
</view>
</view>
</view>
</view>
<view class="no-arr" v-if="icon">
<image src="../../static/no-comment.png" mode=""></image>
<text class="text">没有找到任务呢 <text class="goAdd" @click="goAdd">去发布</text> </text>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: []
}
},
data() {
return {
loading: true,
Hotlist: [],
icon: false
}
},
mounted() {
if (this.list) {
this.Hotlist = this.list
} else {
this.icon = true
}
},
updated() {
this.Hotlist = this.list
},
methods: {
// 去发布
goAdd() {
uni.navigateTo({
url: "/pages/elsetask/elsetask"
})
},
jump(id) {
uni.navigateTo({
url: "/pages/mission/mission?id=" + id,
animationType: 'slide-in-bottom',
animationDuration: 300
});
}
}
}
</script>
<style scoped>
.goAdd {
color: #FF5E00;
margin-left: 20rpx;
}
.list {
position: relative;
}
.no-arr {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 100rpx;
text-align: center;
}
.text {
margin-top: 20rpx;
display: block;
color: #989898;
}
.no-arr>image {
width: 554rpx;
height: 230rpx;
object-fit: cover;
}
.list {
width: 100%;
}
.list-count {
font-weight: 700;
}
.list-list {
display: flex;
flex-direction: column;
margin-top: 20upx;
justify-content: space-between;
background: #fff;
padding: 33upx 32upx;
border-radius: 13upx;
box-shadow: 0 3upx 10upx #00000005;
}
.list-cloumn {
display: flex;
align-items: center;
justify-content: space-between;
}
.list-title {
width: 80%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
font-weight: 700;
color: #050F1A;
font-size: 36upx;
}
.list-price>text {
font-size: 25upx;
}
.list-price {
color: #FF5E00;
font-size: 40upx;
}
.list-cloumn-second {
display: flex;
flex-wrap: wrap;
}
.list-cloumn-margin {
margin-bottom: 10rpx;
}
.list-describes {
display: -webkit-box !important;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.list-menu {
padding: 8upx 23upx;
color: #646566;
font-size: 22upx;
background-color: #F6F7F8;
border-radius: 7upx;
line-height: 1;
margin-right: 10upx;
margin-bottom: 10upx;
}
.list-address>image {
width: 36upx;
height: 36upx;
margin-right: 13upx;
}
.list-address {
display: flex;
color: #969799;
font-size: 24upx;
}
.list-address-text {
color: #969799;
font-size: 24upx;
}
.list-number {
color: #FF5E00;
display: flex;
align-items: center;
}
.list-endTimer {
font-size: 24upx;
}
.list-endColor {
color: #646566 !important;
}
</style>