文章目录
- 前言
- 顶部导航条的实现
- 视频列表的展示部分
- CSS部分
- 最后
前言
接着上篇文章继续完成剩下的部分,本篇文章是完成第二个页面——视频页面的部分,视频还是没有做播放的效果,主要是做展示效果。下面附上两篇文章链接,没看过的同学可以回头看看:
uniapp实战仿写网易云音乐(一)—底部工具栏以及首页轮播图swiper的实现
uniapp实战仿写网易云音乐(二)—promise接口请求的封装和主页功能的实现,组件封装,配置下拉刷新
本篇文章完成的效果动态图:文章底部会附上本页面的css
顶部导航条的实现
首先我们要实现的是顶部的导航条:
如下效果,可以看到它是一个可以向右滑动的导航栏,并且选中的tab下面会有一个导航条的效果。下面来实现:
- 首先一个向右的导航栏我们就可以想到你使用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值(用于获取数据)
- 然后来写下面红色的导航条
由上面效果图可以看出这里的红色导航条的宽度不是固定的,所以我们需要计算导航条的宽度
先在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是下拉和上拉触发的对应的函数
<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到这里就实现了第二个页面的内容,后面会继续更新剩下的页面,感兴趣的可以点一个订阅关注呀~~