概述
应业务需要,制作了简单的瀑布流,应用于购物平台。
首先是单个内容组件。考虑到后台计算的消耗,因而将内容里的图片高度采用直接输入。到时传入数据时需注意。
<!--components/showitems/showitems.wxml-->
<!--展示商品通用框架-->
<view class="showitems-outerbox">
<navigator class="showitems-nav" hover-class="none" url="{{goods.url}}">
<image class="showitems-img" style="height:{{goods.picheight}}px;" lazy-load="{{true}}"></image>
<view class="showitems-text-box">
<view class="showitems-goods-detail">{{goods.detail}}</view>
<view class="showitems-text-bottom">
<view class="showitems-goods-price">¥{{goods.price}}</view>
<view class="showitems-pay-number">{{convertpayers}}人付款</view>
</view>
</view>
</navigator>
</view>
/* components/showitems/showitems.wxss */
/*外框架*/
.showitems-outerbox{
width: 100%;
border-radius: 6px;
overflow: hidden;
background-color: white;
position: relative;
}
/*视图链接*/
.showitems-nav{
width: 100%;
display: block;
}
/*图片*/
.showitems-img{
width: 100%;
display: block;
}
/*文本域*/
.showitems-text-box{
width: 100%;
height: 70px; /*文本域默认高度为70px,可调整*/
}
/*商品描述*/
.showitems-goods-detail{
height: 35px;
width: calc(100% - 20px);
font-size: 12px;
overflow: hidden;
padding: 5px 10px;
}
/*文本域底部*/
.showitems-text-bottom{
height: 20px;
width: calc(100% - 10px);
padding: 0 5px;
display: flex;
align-items: flex-end;
}
/*商品价格*/
.showitems-goods-price{
font-size: 13px;
color: orangered;
padding: 0 5px 0 0;
}
/*付款人数*/
.showitems-pay-number{
font-size: 10px;
color: gray;
}
// components/showitems/showitems.js
Component({
//属性
properties: {
goods:{ //商品信息
type:Object,
value:{
itemsurl:String, //商品链接
picheight:{ //图像高度,默认140px
type:Number,
value:140
},
detail:String, //商品描述
price:Number, //价格
payers:Number, //付款人数
id:Number //商品id
}
},
},
//私有数据
data: {
convertpayers:0, //转化后的购买人数
},
//组件生命周期
lifetimes:{
attached:function(){
var mypayers=this.properties.goods.payers
this.setData({
convertpayers:mypayers>9999?(Math.floor(mypayers/10000)+'万+'):mypayers
})
}
},
//方法
methods: {
}
})
接下来是瀑布流组件,注意与外部页面联动。加载的数据需在外部页面JSON化后传入。初始加载20个项目,且每次触底都加载20个项目,但总数尽量不要超过200个,否则可能会卡顿。可简单实现删除一个项目后从外部传入新数据并重新排布序列。组件宽度默认屏幕宽度,可按需嵌套在容器中。最后,在该组件的JSON文件中需引用上述的项目组件,这两个组件有关联。
<!--components/waterfall/waterfall.wxml-->
<!--瀑布流布局-->
<view class="waterfall-outer">
<view class="waterfall-left">
<block wx:for="{{itemsleft}}" wx:key="index">
<view class="waterfall-itemsbox" catchlongpress="_showmask" data-id="{{item.id}}">
<showitems goods="{{item}}"></showitems>
<view class="waterfall-threedots" catchtap="_showmask" data-id="{{item.id}}">...</view>
<view class="waterfall-mask" wx:if="{{item.id==maskid && isshowmask}}" catchtap="_hidemask">
<view class="waterfall-mask-unlike" catchtap="_unlike">不喜欢</view>
</view>
</view>
</block>
</view>
<view class="waterfall-right">
<block wx:for="{{itemsright}}" wx:key="index">
<view class="waterfall-itemsbox" catchlongpress="_showmask" data-id="{{item.id}}">
<showitems goods="{{item}}"></showitems>
<view class="waterfall-threedots" catchtap="_showmask" data-id="{{item.id}}">...</view>
<view class="waterfall-mask" wx:if="{{item.id==maskid && isshowmask}}" catchtap="_hidemask">
<view class="waterfall-mask-unlike" catchtap="_unlike">不喜欢</view>
</view>
</view>
</block>
</view>
</view>
<view class="waterfall-bottom" hidden="{{!istobottom}}">到底了~</view>
/* components/waterfall/waterfall.wxss */
/*瀑布流框架*/
.waterfall-outer{
width: 100%;
display: flex;
justify-content: space-between;
}
/*左侧、右侧*/
.waterfall-left , .waterfall-right{
width: calc(50% - 4px); /*中间留8px*/
}
/*项目盒子*/
.waterfall-itemsbox{
width: 100%;
position: relative;
margin-bottom: 8px; /*底部空余8px*/
}
/*三点*/
.waterfall-threedots{
font-size: 16px;
color: gray;
position: absolute;
right: 8px;
bottom: 8px;
height: 18px;
width: 14px;
}
/*蒙层*/
.waterfall-mask{
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/*不喜欢*/
.waterfall-mask-unlike{
width: 80px;
height: 20px;
font-size: 14px;
position: absolute;
margin-bottom: 10px;
background-color: white;
text-align: center;
border-radius: 5px;
color: gray;
}
/*瀑布流底部*/
.waterfall-bottom{
height: 30px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: gray;
}
// components/waterfall/waterfall.js
Component({
//组件属性
properties: {
msg:{ //商品相关信息,在页面JSON化后传入
type:Array,
value:[{
itemsurl:String, //商品链接
picheight:{ //图像高度,默认140px
type:Number,
value:140
},
detail:String, //商品描述
price:Number, //价格
payers:Number, //付款人数
id:Number //商品id
}]
},
loadmore:{ //滚动条触底加载更多,作为页面接口,配合cancelloadmore函数
type:Boolean,
value:false
},
isshowmask:{ //是否显示图片蒙层,作为页面接口,点击空白取消蒙层
type:Boolean,
value:false
},
convey:{ //页面接口,若数据更新完毕传入新的msg序列,则将其设置为true
type:Boolean,
value:false
}
},
//组件内部数据
data: {
leftheight:0, //左侧高度
rightheight:0, //右侧高度
itemsleft:[], //左侧数据集
itemsright:[], //右侧数据集
pageorder:0, //加载页数
istobottom:false, //是否页面到底
maskid:null, //蒙层id
msgarray:[], //动态渲染信息列表
absposition:0, //信息在瀑布流中的绝对位置
},
//生命周期
lifetimes:{
attached:function(){
var leftheight=0
var rightheight=0
var itemsleft=[]
var itemsright=[]
for(let i=0;i<(this.properties.msg.length<=20?this.properties.msg.length:20);i++){ //初始渲染20张图片,不到20张则渲染全部
if(leftheight<=rightheight){
itemsleft.push(this.properties.msg[i])
leftheight += this.properties.msg[i].picheight+70+8 //加上70px文本域高度h和8px边距
}
else{
itemsright.push(this.properties.msg[i])
rightheight += this.properties.msg[i].picheight+70+8
}
}
this.setData({
leftheight:leftheight,
rightheight:rightheight,
itemsleft:itemsleft,
itemsright:itemsright,
pageorder:this.data.pageorder+1,
msgarray:this.properties.msg.slice(0,20) //设置初始渲染列表
})
},
},
//页面生命周期
pageLifetimes:{
hide:function(){
this._hidemask()
}
},
//数据监听
observers:{
'loadmore':function(newval){
if(newval){ //产生加载请求
let leftheight=this.data.leftheight
let rightheight=this.data.rightheight
let itemsleft=this.data.itemsleft
let itemsright=this.data.itemsright
let pageorder=this.data.pageorder
if(this._pagerelation()!=0){ //未到最后一页
for(let i=0;i<this._remainitems();i++){
if(leftheight<=rightheight){
itemsleft.push(this.properties.msg[i+pageorder*20])
leftheight += this.properties.msg[i+pageorder*20].picheight+70+8
}
else{
itemsright.push(this.properties.msg[i+pageorder*20])
rightheight += this.properties.msg[i+pageorder*20].picheight+70+8
}
}
this.setData({
leftheight:leftheight,
rightheight:rightheight,
itemsleft:itemsleft,
itemsright:itemsright,
pageorder:pageorder+1,
msgarray:this.properties.msg.slice(0,this.data.msgarray.length+this._remainitems()) //更新动态渲染信息列表
})
}
else{ //到最后一页
this.setData({
istobottom:true
})
}
this._cancelloadmore() //取消加载更多标记
}
},
'convey':function(newval){
if(newval){ //重置瀑布流
let leftheight=0
let rightheight=0
let itemsleft=[]
let itemsright=[]
this.data.msgarray=this.properties.msg.slice(0,this.data.msgarray.length)
for(let i=0;i<this.data.msgarray.length;i++){
if(leftheight<=rightheight){
itemsleft.push(this.data.msgarray[i])
leftheight += this.data.msgarray[i].picheight+70+8
}
else{
itemsright.push(this.data.msgarray[i])
rightheight += this.data.msgarray[i].picheight+70+8
}
}
this.setData({
itemsleft:itemsleft,
itemsright:itemsright,
leftheight:leftheight,
rightheight:rightheight
})
this._cancelconvey() //取消数据传送完毕标记
}
}
},
//组件方法
methods: {
_totalpagenum(){ //20张一页,共几页
var msglength=this.properties.msg.length
return msglength%20==0?Math.floor(msglength/20):Math.floor(msglength/20+1)
},
_pagerelation(){ //判断页数情况
var totalpage=this._totalpagenum()
var curpage=this.data.pageorder
return (totalpage-curpage==0)?0:((totalpage-curpage==1)?1:2)
},
_remainitems(){ //剩余项目
switch(this._pagerelation()){
case 0: return 0;
case 1: return this.properties.msg.length-this.data.pageorder*20;
case 2: return 20;
default: return 0;
}
},
_cancelloadmore(){ //发送取消加载更多标记的请求,关联loadmore接口
this.triggerEvent('cancelloadmore')
},
_showmask(e){ //显示蒙层
this.setData({
maskid:e.currentTarget.dataset.id,
isshowmask:true
})
},
_hidemask(){ //取消蒙层
this.setData({
isshowmask:false
})
},
_unlike(){ //点击不喜欢按钮
for(let i=0;i<this.data.msgarray.length;i++){
if(this.data.msgarray[i].id==this.data.maskid){ //按钮id和蒙层id相同
this.setData({
absposition:i
})
break
}
}
this.triggerEvent('needonemsg',{position:this.data.absposition}) //发送请求通知页面更新消息列表,关联convey接口
},
_cancelconvey(){ //发送清除convey标识的请求,关联convey接口
this.triggerEvent('cancelconvey')
},
}
})
用法举例:
新建一个页面,在wxml页输入
<view style="width:calc(100% - 20px);margin:10px;" bindtap="_clickspace">
<waterfall msg="{{mymessage}}" loadmore="{{istolast}}" bind:cancelloadmore="_cancelloadmore" isshowmask="{{haveshowmask}}" convey="{{myconvey}}" bind:needonemsg="_needonemsg" bind:cancelconvey="_cancelconvey"></waterfall>
</view>
在js页面输入
data: {
mymessage:[{itemsurl:'',picheight:150,detail:'会地方的基础上',price:245,payers:4567,id:0},
{itemsurl:'',picheight:130,detail:'很合适的十多个',price:356,payers:233,id:1},
{itemsurl:'',picheight:140,detail:'电话手表编程',price:377.9,payers:12,id:2},
{itemsurl:'',picheight:160,detail:'当回事呢购物',price:7899,payers:54761,id:3},
{itemsurl:'',picheight:140,detail:'变成蛇的差别不大',price:245,payers:4567,id:4},
{itemsurl:'',picheight:160,detail:'的接口处超声波产生',price:245,payers:4567,id:5},
{itemsurl:'',picheight:150,detail:'会地方的基础上',price:245,payers:4567,id:6},
{itemsurl:'',picheight:130,detail:'会地方的基础上',price:245,payers:4567,id:7},
{itemsurl:'',picheight:160,detail:'会地方的基础上',price:245,payers:4567,id:8},
{itemsurl:'',picheight:130,detail:'会地方的基础上',price:245,payers:4567,id:9},
{itemsurl:'',picheight:150,detail:'会地方的基础上',price:245,payers:4567,id:10},
{itemsurl:'',picheight:150,detail:'会地方的基础上',price:245,payers:4567,id:11},
{itemsurl:'',picheight:170,detail:'会地方的基础上',price:245,payers:4567,id:12},
{itemsurl:'',picheight:140,detail:'会地方的基础上',price:245,payers:4567,id:13},
{itemsurl:'',picheight:160,detail:'会地方的基础上',price:245,payers:4567,id:14},
{itemsurl:'',picheight:160,detail:'会地方的基础上',price:245,payers:4567,id:15},
{itemsurl:'',picheight:150,detail:'会地方的基础上',price:245,payers:4567,id:16},
{itemsurl:'',picheight:140,detail:'会地方的基础上',price:245,payers:4567,id:17},
{itemsurl:'',picheight:150,detail:'武松要打虎',price:245,payers:4567,id:18},
{itemsurl:'',picheight:140,detail:'会地方的基础上',price:245,payers:4567,id:19},
{itemsurl:'',picheight:140,detail:'会地方的基础上',price:245,payers:4567,id:20},
{itemsurl:'',picheight:160,detail:'我在河边洗澡',price:245,payers:4567,id:21}
],
istolast:false,
haveshowmask:false,
myconvey:false,
},
//监听页面触底
onReachBottom:function(){
this.setData({
istolast:true
})
},
//取消加载标记
_cancelloadmore:function(){
this.setData({
istolast:false
})
},
//取消蒙层
_clickspace:function(){
this.setData({
haveshowmask:false
})
},
//需要新消息
_needonemsg:function(e){
this.data.mymessage.splice(e.detail.position,1)
this.data.mymessage.push({itemsurl:'',picheight:170,detail:'好像是睡觉一样的人大概是动感',price:371,payers:1356,id:22})
this.setData({
haveshowmask:false
})
var i=setTimeout(() => {
this.setData({
myconvey:true,
mymessage:this.data.mymessage
})
clearTimeout(i)
}, 1000);
},
//取消新消息标识位
_cancelconvey:function(){
this.setData({
myconvey:false
})
},
最后在JSON页面引用waterfall组件,便可看到有趣的现象。祝大家玩得愉快!
最后
以上就是粗心银耳汤为你收集整理的关于微信小程序简单瀑布流的制作的全部内容,希望文章能够帮你解决关于微信小程序简单瀑布流的制作所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复