最近开始将自己写的一些小程序开源到GitHub上面,为的是更好检验自己的编程能力,为自己后面的开源项目走出一条新的道路。
我们先看看我的小程序首页效果图
主要功能:我的订阅和近期热门和最新内容支持左右滑动,模仿SF思否app交互式,嵌入一个swiper和N个scroll-view这样我们就可以分开视图滚动和切换视图。
以下是核心代码
<view class='index_swiper'>
<swiper bindchange="changSwiper" current="{{ indexValue }}" style="height:calc(100vh - {{paddingValue}}px)">
<block wx:for="{{ containerData }}" wx:key="container{{ index }}">
<swiper-item>
<scroll-view scroll-y style="height:inherit" bindscrolltolower="scrolltolower" data-index='{{ index }}'>
<view class='index_swiper_box' id="{{ item.name }}">
<block wx:for="{{ item.data }}" wx:key="item{{ index }}">
<homeModule></homeModule>
</block>
</view>
</scroll-view>
</swiper-item>
</block>
</swiper>
</view>
height:calc(100vh - {{paddingValue}}px)的意思是获取屏幕高度减去头部搜索加选择的头部就可以得出我们swiper的高度,由于我们想做到多个滑动视图,我们需要去通过数据进行配置
tabData: [{
text: "我的订阅"
},
{
text: "近期热门"
},
{
text: "最新内容"
},
],
这个是配置选择的头部
containerData: [{
name: 'subscribe',
data: [1, 2, 3]
},
{
name: 'hot',
data: [1, 2, 3, 5, 6, 5, 6, 5]
},
{
name: 'newest',
data: [1, 2, 3, 6, 5]
}
]
},
这个是配置scroll-view的数量 name:求换到第几个的id类似于锚点 data是数据,因为我们没有服务端,就只能写一个组件通过data去渲染数据。
核心js代码:
selectOne: function(e) {
//用于用户用户使用滑动切换触发头部对用位置更新
this.setData({
indexValue: e.currentTarget.dataset.index,
});
},//用于点击选择的头部切换到相应的位置
changSwiper: function(res) {
if (res.detail.source == "touch") {
this.setData({
// 获取到当前侧滑的索引
indexValue: res.detail.current,
});
}
},
scrolltolower:function(res){
//用于scroll-view模拟用户滚动到底部,加载更多,因为我这边没有服务器,就只能用数组去模拟从服务器获取到数据
var index = res.currentTarget.dataset.index;
var data = [...this.data.containerData[index].data, ...[2, 5, 6, 8]]
var name = `containerData[${index}].data`;
console.log(name);
this.setData({
[name]: data
})
}
这样我们就可以实现类似于掘金小程序上首页滑动切换视图
我的发现模块主要是一些组件嵌入进去,比较麻烦就是轮播图那块,我已经将他写成一个组件,为下个讲堂模块复用,这一块相信大家都可以实现的,我也把代码上传到GitHub上面,有兴趣的可以上去看看。
我们主要看看顶部那块标题,他的交互是根据你的滚动的位置去控制标题的字体大小和位置
我们看核心代码
<view class='navigation' style=' background-color:{{ color }}'>
<view class='navigation_box'>
<view class='navigation_box_return' bindtap='callBack'>
<image src='./image/return.svg'></image>
</view>
<view class='navigation_box_image' bindtap='showSearch' wx:if="{{ search }}">
<image src='./image/search.svg'></image>
</view>
<view class='navigation_box_image narrow' bindtap='showEdit' wx:if="{{ edit }}">
<image src='./image/edit.svg'></image>
</view>
</view>
<view class='navigation_text' style='font-size:{{ defaultFace }}px;margin-top:{{ marginTop }}px; margin-left: {{ marginLeft }}px'>
<text>{{ title }}</text>
</view></view>
properties: {
title: {
//接收传过来的标题名称
type: String
},
searchValue: {
//接收传过来是否显示搜索按钮
type: String,
observer: function(newVal) {
var flag = newVal == "false" ? false : true;
this.setData({
search: flag
});
}
},
editValue: {
//接收传过来是否显示编辑按钮
type: String,
observer: function(newVal) {
var flag = newVal == "false" ? false : true;
this.setData({
edit: flag
});
}
},
top: {
//接收传过来是否滚动的值
type: Number,
observer: function(newVal, oldVal, changedPath) {
this.setData({
currentValue: newVal
});
var deviation = newVal - oldVal; //向下滚动的偏差值
var devContrary = oldVal - newVal; //向上滚动的偏差值
if (deviation > 0) {
var mt = this.data.marginTop - deviation / 4 <= -25 ? -25 : this.data.marginTop - deviation / 4;
var ml = this.data.marginLeft + deviation / 2.5 >= 50 ? 50 : this.data.marginLeft + deviation / 2.5;
var faceValue = this.data.defaultFace - deviation / 10 <= 20 ? 20 : this.data.defaultFace - deviation / 10;
if (this.data.currentValue <= 125) { var colorValue = "transparent";
} else {
var colorValue = "#fff";
}
} else {
if (this.data.currentValue <= 125) {
var mt = this.data.marginTop + devContrary / 4 >= 10 ? 10 : this.data.marginTop + devContrary / 4;
var ml = this.data.marginLeft + deviation / 2.5 <= 0 ? 0 : this.data.marginLeft + deviation / 2.5;
var faceValue = this.data.defaultFace + devContrary / 10 >= 30 ? 30 : this.data.defaultFace + devContrary / 10;
var colorValue = "transparent";
} else {
var mt = -25;
var ml = 50;
var faceValue = 20;
var colorValue = "#fff";
}
}
this.setData({
marginTop: mt,
marginLeft: ml,
defaultFace: faceValue,
color: colorValue
})
}
}, bgColor: {
//接收传过来的背景颜色
type: String,
observer: function(newVal) {
this.setData({
color: newVal
});
}
}
},
我们通过接收值的方式,拿到相应导航栏的配置,接收滚动的位置,通过老值和新值相减来知道是向下滚动还是向上滚动,这样我们通过三元表达式来知道是否超出我们规定的一个值,因为我们滚动的值会越来越大,我们需要去除以一个整数来使得这个标题的变化更明显。
讲堂这个模块也是如此,好多的复用组件插入进来,这个部分很简单
消息模块是一个静态页面,由于时间问题,我现在没有开发
这是我的模块,里面大多数功能我已经实现好了,主要逻辑也是组件,文件配置等,这部分我会下章为大家详细讲解,由于开发周期才差不多一个月好多东西我都没有弄好,抱歉,能力有限,在后面的时间我会完善这些功能项目差不多有20多个页面和10几个组件,我觉得在这个项目中学到好多小程序的知识,特意写这篇文章给大家分享一下。
最后,附上项目的GitHub地址:SF思否小程序
文章转载请联系我:qq:652165177,请不要用于商业用途,如有版权问题请联系我!