内容介绍
今天我们要写的是滚动条下拉实现从缓冲中到缓冲完瀑布流形式的效果。 下面看效果图
Home.vue组件
本组件中引入了menu-card 和Waterfall 两个子组件,下面开始获取api中的数据。在moutend中获取getBanner和getMenus的list,把list中的数据在赋值给data 中的banners和getMenus数组
import MenuCard from '@/components/menu-card.vue'
import Waterfall from '@/components/waterfall.vue'
import {getBanner,getMenus} from '@/service/api.js'
export default {
name: 'home',
components: {
MenuCard: MenuCard,
Waterfall
},
data(){
return {
banners:[],
menuList:[],
page:1,
pages:5
}
},
mounted(){
getBanner().then(({data})=>{
this.banners=data.list
})
getMenus({page:this.page}).then(({data})=>{
console.log(data);
this.menuList=data.list
this.pages=Math.ceil(data.total/data.page_size)
})
},
利用v-for把banners数据渲染出来。banners是本页面的渲染数据。在waterfall标签中自定义一个view事件,从而实现跨组件操作数据。menu-card标签中用绑定info来获取data中的menuList,在menu-card组件中实现渲染数据
<template>
<div class="home">
<el-carousel :interval="5000" type="card" height="300px">
<el-carousel-item v-for="item in banners" :key="item._id">
<router-link :to="{name:'detail',query:{menuId:item._id}}">
<img
:src="item.product_pic_url"
width="100%"
alt=""
>
</router-link>
</el-carousel-item>
</el-carousel>
<div>
<h2>内容精选</h2>
<waterfall ref="waterfall" @view='loadingMenuHanle'>
<menu-card :margin-left="13" :info='menuList'></menu-card>
</waterfall>
</div>
</div>
</template>
methods中的loadingMenuHanle函数是操作从第一页五个数据滚动条下拉到底时加载数据自增,判断menu-card页面中的数据全部加载完和单页面大于总页面时下面的小花花为flase还是true。
methods:{
loadingMenuHanle(){
this.page++
if(this.page > this.pages){
this.$refs.waterfall.isshow = false;
return;
}
this.$refs.waterfall.isshow = true;
getMenus({page:this.page}).then(({data})=>{
console.log(data);
this.menuList.push(...data.list)
this.$refs.waterfall.isshow = false;
})
}
}
}
waterfall.vue组件
slot标签是一个为menu-card组件的数据做的一个占位符。
<template>
<div class="waterfall" ref="waterfall">
<slot></slot>
<div class="waterfall-loading" ref='loading' v-show="isshow">
<i class="el-icon-loading"></i>
</div>
</div>
</template>
data中的属性是来判断下拉加载数据时小花花的显示或隐藏。methods中的scoll函数,判断元素到可视区下面小于可视区的高度时小花花为false,从而emit自定义事件跨组件操作。mounted中操作的是每隔一段时间去执行scoll函数,不让它重复触发使用的是节流函数,记得要引入节流模块哦。
import {throttle} from "throttle-debounce"
export default {
name: 'Waterfall',
data(){
return {
isshow:false
}
},
mounted(){
this.scrollHanle = throttle(300,this.scroll);
window.addEventListener('scroll',this.scrollHanle)
},
destroyed(){
window.removeEventListener('scroll',this.scrollHanle)
},
methods:{
scroll(){
if(this.isshow) return;
if(this.$refs.waterfall.getBoundingClientRect().bottom < document.documentElement.clientHeight){
console.log("已到达可视区");
this.isshow = true;
this.$emit("view");
}
}
}
}
menu-card.vue组件
以下步骤就是在页面中循环显示数据,记得我们上一步在Home组件中绑定的info吗,它绑定的通过后端获取的数据赋值给menuList属性,所以直接通过info循环数据显示即可
export default {
name: 'menu-card',
props:{
marginLeft: {
type: Number,
default: 22
},
info:{
type: Array,
default:() => []
},。
}
}
<template>
<el-row class="menu-card" type="flex" justify="start">
<el-col style="flex:none;" :style="{'margin-left':marginLeft+'px'}" v-for="item in info" :key="item.id">
<el-card :body-style="{ padding: '0px' }" >
<router-link :to="{naem:'detail',query:{menuId:item._id}}">
<img :src="item.product_pic_url" class="image" style="width: 232px;height: 232px;">
<div style="padding: 14px;" class="menu-card-detail">
<strong>菜品名称:{{item.title}}</strong>
<span>{{item.comments_len}} 评论</span>
<router-link :to="{naem:'space',query:{userId:item.userId}}" tag="em">
作者:{{item.name}}
</router-link>
</div>
</router-link>
</el-card>
</el-col>
</el-row>
</template>
完毕
|