uniapp实战仿写网易云音乐(三)—视频页面(scroll-view组件实现横线滑动,mescroll-uni实现视频列表,向下滑动刷新当前页面)

前言

接着上篇文章继续完成剩下的部分,本篇文章是完成第二个页面——视频页面的部分,视频还是没有做播放的效果,主要是做展示效果。下面附上两篇文章链接,没看过的同学可以回头看看:
uniapp实战仿写网易云音乐(一)—底部工具栏以及首页轮播图swiper的实现
uniapp实战仿写网易云音乐(二)—promise接口请求的封装和主页功能的实现,组件封装,配置下拉刷新

本篇文章完成的效果动态图:文章底部会附上本页面的css
在这里插入图片描述

顶部导航条的实现

首先我们要实现的是顶部的导航条:
如下效果,可以看到它是一个可以向右滑动的导航栏,并且选中的tab下面会有一个导航条的效果。下面来实现:
在这里插入图片描述

  1. 首先一个向右的导航栏我们就可以想到你使用scroll-view来实现:
    scroll-x="true"就是可以横向滑动
<scroll-view class="scroll-view" scroll-x="true" :show-scrollbar="false">
	<view class="rel">
	<!-- 导航条 -->
		<view class="item" v-for="(item,index) in navList" :key="index" 
		:class="{active: curNav==item.id}" @click="switchNav(item.id, index)">
			<view class="desc">
				{
    
    {
    
    item.name}}
			</view>
		</view>
	</view>
</scroll-view>

:class绑定高亮的样式
这里点击绑定了switchNav事件,用于更改选中项的id值(用于获取数据)

  1. 然后来写下面红色的导航条
    由上面效果图可以看出这里的红色导航条的宽度不是固定的,所以我们需要计算导航条的宽度
    先在data中定义 导航条默认宽度 和 导航条偏移量
data() {
    
    
	return {
    
    
		navList: [],                      //导航条
		curNav: '',                       //当前选中的导航条
		sliderWidth: 60,                  //导航条默认宽度
		sliderOffset:26,                  //导航条偏移量
	}
},

然后来写一个导航条,给动态的样式:

<view class="slide" 
:style="'width:'+sliderWidth+'rpx;transform:translateX('+sliderOffset+'rpx)'">
	
</view>

接下来就是点击导航栏的时候修改宽度和偏移量的值:

//导航条高亮切换
switchNav(itemId, index) {
    
    
	this.curNav = itemId;
	//导航条的宽度  140是第1项的宽度
	this.sliderWidth = index===1 ? 140: 60;
	//计算偏移量 左边16 文字60+间隙64=124   LOCK=80
	this.sliderOffset = 124*index + (index > 1 ? 80: 16)
},

导航条完整的样式:

<scroll-view class="scroll-view" scroll-x="true" :show-scrollbar="false">
	<view class="rel">
	<!-- 导航条 -->
		<view class="item" v-for="(item,index) in navList" :key="index" 
		:class="{active: curNav==item.id}" @click="switchNav(item.id, index)">
			<view class="desc">
				{
    
    {
    
    item.name}}
			</view>
		</view>
		<!-- 下划线 -->
		<view class="slide" 
		:style="'width:'+sliderWidth+'rpx;transform:translateX('+sliderOffset+'rpx)'">
		</view>
	</view>
</scroll-view>

视频列表的展示部分

开始实现视频列表的部分:
在这里插入图片描述
视频列表这里我们使用mescroll-uni组件来实现:
这里贴一下这个外部控件的官方文档:mescroll-uni
这里要实现的是一个分页,向上滚动到要能加载下一页,向下滚动要能刷新当前页,这些功能只需要配置对应的属性
先在data中定义需要用到的参数:

downOption: {
    
                         //下拉刷新
	auto: false
},
upOption: {
    
                           //上拉加载下一页
	auto: false,
	page: {
    
    
		num: 0,                   //起始页
		size: 10,                 //一页条数
	}
},

@down和@up是下拉和上拉触发的对应的函数

扫描二维码关注公众号,回复: 15720940 查看本文章
<mescroll-uni :down="downOption" :up="upOption" @down="downCallback" @up="upCallback">
	<view class="video-list">
		<view class="video-item" v-for="(item, index) in relatedVideo" :key="index">
			<view class="video-wrap">
				<image :src="item.coverUrl" mode="" class="img"></image>
				<view class="desc ellipsis">
					{
    
    {
    
    item.title}}
				</view>
				<view class="creater-bar flex-box">
					<view class="name">
						{
    
    {
    
    item.creator[0].userName}}
					</view>
				</view>
			</view>
		</view>
	</view>
</mescroll-uni>

然后在函数中进行对应的操作:

//下拉刷新回调
downCallback(mescroll) {
    
    
	console.log("downcallback")
	//重置列表为第一页(自动执行page.num=1,再触发upcallback方法)
	mescroll.resetUpScroll();
},
//上拉加载回调
upCallback(mescroll) {
    
    
	console.log("upcallback", mescroll)
	//加载下一页数据
	this.getList(mescroll.num, mescroll.size, res=> {
    
    
		//若是第一页 则清空
		if (mescroll.num == 1) {
    
    
			this.relatedVideo = [];
		}
		//累加数据
		this.relatedVideo = this.relatedVideo.concat(res);
		//成功的回调,隐藏刷新状态
		mescroll.endSuccess();
	}, ()=>{
    
    
		//失败的回调,隐藏下拉刷新状态
		mescroll.endErr();
	})
}

CSS部分

<style lang="scss">
	.topbar {
    
    
		.h86 {
    
    
			height: 86rpx;
		}
	}

	.scroll-view {
    
    
		position: fixed;
		top: 0;
		width: 100%;
		height: 86rpx;
		white-space: nowrap;
		text-align: center;
		line-height: 86rpx;
		color: #333;
		font-weight: 600;
		border-bottom: 1rpx solid #e6e6e6;
		z-index: 10;
		background: #fff;
		.item {
    
    
			position: relative;
			display: inline-block;
			min-width: 126rpx;
			height: 86rpx;
			line-height: 86rpx;
			padding: 0 20rpx;
			&.active{
    
    
				color:#f32628;
			}
		}
	}

	.slide {
    
    
		position: absolute;
		width: 60rpx;
		height: 4rpx;
		left: 0;
		bottom: 0rpx;
		background: #f32628;
		transition: transform 0.3s;
		z-index: 2;
		/* #ifdef MP-WEIXIN */
		bottom: 2rpx;
		/* #endif */
	}

	.video-list {
    
    
		color: #333;
		background: #f8f8f8;
		.tit-bar {
    
    
			padding-left: 32rpx;
		}
		.video-item {
    
    
			padding-top: 32rpx;
			background: #fff;
			border-bottom: 24rpx solid #f8f8f8;
		}

		.video-wrap {
    
    
			width: 686rpx;
			margin: 0 auto;
		}

		.img {
    
    
			display: block;
			width: 686rpx;
			height: 390rpx;
			border-radius: 10rpx;
			background: #eee;
		}

		.desc {
    
    
			font-size: 30rpx;
			font-weight: 600;
			line-height: 84rpx;
			border-bottom: 1rpx solid #e6e6e6;
		}
	}

	.creater-bar {
    
    
		height: 100rpx;
		justify-content: space-between;
		align-items: center;
		.avactor-box {
    
    
			align-items: center;
		}
		.avactor {
    
    
			width: 66rpx;
			height: 66rpx;
			margin-right: 10rpx;
			border-radius: 66rpx;
			background: #eee;
		}

		.name {
    
    
			line-height: 100rpx;
		}
	}
</style>

最后

ok到这里就实现了第二个页面的内容,后面会继续更新剩下的页面,感兴趣的可以点一个订阅关注呀~~

猜你喜欢

转载自blog.csdn.net/weixin_45745641/article/details/128349024
今日推荐