用vant实现下拉刷新,超简单
官网:vant-ui.github.io/vant/v3/#/z…
效果图
demo
安装
npm install vant --save
全局注册
在main.js文件中:
import Vant from 'vant'
import 'vant/lib/index.css'
import { PullRefresh } from 'vant'
app.use(Vant)
app.use(PullRefresh)
使用
在需要应用的vue文件中:
<template>
<van-pull-refresh
v-model="loading"
@refresh="onRefresh"
class="product_card"
>
<van-list
v-model="downLoading"
:finished="downFinished"
:immediate-check="false"
finished-text="All products are here ~"
@load="onLoad"
:offset="20"
class="product_list"
>
<li
class="product_item"
v-for="(product, product_index) of productList"
:key="product_index"
:data-index="product_index"
:data-name="product.name"
:data-brand="product.brand"
:data-price="product.price"
@click="chooseProduct(product)"
>
<div class="img_box">
<img :src="product.image" class="product_img" />
</div>
<div class="text_box">
<div class="title">{{ product.name }}</div>
<div class="brand">{{ product.brand }}</div>
<div class="price">$ {{ Number(product.price).toFixed(2) }}</div>
<div class="card_cart" @click.stop="addToCart(product, $event)">
<i
class="iconfont icon-gouwudai"
:class="
isAdd == true && actived_cardIndex == product_index
? 'icon-gouwudai_purple'
: 'icon-gouwudai'
"
></i>
</div>
</div>
</li>
</van-list>
</van-pull-refresh>
<van-loading
type="spinner"
color="#a456dd"
size="24px"
v-if="downLoading == true"
class="loading_icon"
/>
<template>
import { Toast_Info } from '@/utils/extract'
import { throttle } from 'lodash'
/ 下拉刷新
const loading = ref(false)
const onRefresh = async () => {
setTimeout(async () => {
Toast_Info('刷新成功')
loading.value = false
}, 1000)
const data3 = {
size: 10,
page: 1,
barCode: '',
name: ''
}
// get更多商品列表信息
const resp_getGoodsList = await getGoodsList(data3)
console.log('get商品列表信息', resp_getGoodsList)
if (resp_getGoodsList.errCode == 1000) {
productList.length = 0
Object.assign(productList, resp_getGoodsList.data.list)
count_product.value = productList.length
} else {
}
}
// 上拉加载
const downLoading = ref(false)
const downFinished = ref(false)
const count1 = ref(1)
const onLoad = throttle(async () => {
downLoading.value = true
setTimeout(async () => {
downLoading.value = false
count1.value++
const data2 = {
size: 10,
page: count1.value,
barCode: '',
name: ''
}
// get更多商品列表信息
const resp_getGoodsList = await getGoodsList(data2)
console.log('get商品列表信息', resp_getGoodsList)
// 判断没有新数据了
if (productList.length == resp_getGoodsList.data.total) {
downFinished.value = true
}
if (resp_getGoodsList.errCode == 1000) {
resp_getGoodsList.data.list.forEach((item) => {
productList.push(item)
})
count_product.value = productList.length
} else {
}
}, 300)
}, 1000)
逻辑说明
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用 防抖debounce 和 节流throttle 的方式来减少调用频率
debounce: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时throttle: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
这里加了debounce防抖函数,时间是300毫秒,只执行用户第一次上拉加载
<style lang="scss" scoped>
.product_card {
width: 350px;
height: 80vh;
overflow: auto;
margin-top: 16px;
// ul
.product_list {
list-style-type: none;
display: flex;
flex-wrap: wrap;
// li
.product_item {
width: 160px;
height: 198px;
border-radius: 8px;
background-color: #f9f9fb;
padding-bottom: 8px;
margin: 0 7.5px 16px 7.5px;
.img_box {
.product_img {
width: 160px;
height: 112px;
border-radius: 8px;
}
}
.text_box {
width: 136px;
height: 63px;
margin: 12px 0 12px 12px;
position: relative;
.title {
font-size: 15px;
color: #001c33;
}
.brand {
font-size: 12px;
line-height: 28px;
color: #a2a2a3;
}
.price {
font-size: 17px;
color: #001c33;
margin-top: 5px;
}
.card_cart {
width: 32px;
height: 32px;
border-radius: 50px;
background-color: #f2f4f5;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
right: -2px;
bottom: -8px;
.icon-gouwudai {
font-size: 17px;
margin-top: -2px;
}
.icon-gouwudai_purple {
color: #a456dd;
}
}
}
}
}
}
.product_card::-webkit-scrollbar {
display: none;
}
.loading_icon {
position: absolute;
bottom: 3vh;
}
<style />
样式说明
<van-pull-refresh>要有一个固定的高度,且要做溢出处理overflow: auto,不然不能判断是否到底<van-loading />位置可以写死,用vh作单位<van-list>用list-style-type: none去除默认样式<van-pull-refresh>用::-webkit-scrollbar去除滚动条