使用Vant框架list組件遇到的坑及解決
使用Vant框架list組件的坑
介紹
Vant 是有贊前端團(tuán)隊(duì)開(kāi)源的移動(dòng)端組件庫(kù),于 2017 年開(kāi)源,已持續(xù)維護(hù) 4 年時(shí)間。
Vant 對(duì)內(nèi)承載了有贊所有核心業(yè)務(wù),對(duì)外服務(wù)十多萬(wàn)開(kāi)發(fā)者,是業(yè)界主流的移動(dòng)端組件庫(kù)之一。
特性
- 提供 60 多個(gè)高質(zhì)量組件,覆蓋移動(dòng)端各類場(chǎng)景
- 性能極佳,組件平均體積不到 1kb(min+gzip)
- 單元測(cè)試覆蓋率 90%+,提供穩(wěn)定性保障
- 完善的中英文文檔和示例
- 支持 Vue 2 & Vue 3
- 支持按需引入
- 支持主題定制
- 支持國(guó)際化
- 支持 TypeScript
- 支持 SSR
快速配置和具體介紹請(qǐng)去官方文檔,Vant框架在Github上點(diǎn)贊眾多,用起來(lái)發(fā)現(xiàn)還是很好用的,強(qiáng)力推薦
聊一下使用list組件遇到的坑
官方文檔的實(shí)例代碼是這樣的:
<van-list v-model="loading" :finished="finished" finished-text="沒(méi)有更多了" @load="onLoad" > <van-cell v-for="item in list" :key="item" :title="item" /> </van-list> export default { data() { return { list: [], loading: false, finished: false, }; }, methods: { onLoad() { // 異步更新數(shù)據(jù) // setTimeout 僅做示例,真實(shí)場(chǎng)景中一般為 ajax 請(qǐng)求 setTimeout(() => { for (let i = 0; i < 10; i++) { this.list.push(this.list.length + 1); } // 加載狀態(tài)結(jié)束 this.loading = false; // 數(shù)據(jù)全部加載完成 if (this.list.length >= 40) { this.finished = true; } }, 1000); }, }, };
效果圖片:
可是!你復(fù)制代碼,發(fā)現(xiàn),發(fā)現(xiàn)完全不好用!這個(gè)定時(shí)任務(wù)簡(jiǎn)直看不懂,觸底加載簡(jiǎn)直毫無(wú)邏輯,通過(guò)幾個(gè)小時(shí)的研究,發(fā)現(xiàn)問(wèn)題所在居然是CSS!對(duì),你沒(méi)有聽(tīng)錯(cuò)!是CSS導(dǎo)致的!
下方代碼,重點(diǎn)看css部分,JS部分,記住settimeout不要去掉,不要相信他的注釋,業(yè)務(wù)寫在settimeout里就可以了
解釋一下這個(gè)css的含義,就是van-list需要給他定義一個(gè)高度,并且滾動(dòng)自適應(yīng),這樣在不填滿高度或者是滾動(dòng)觸底的時(shí)候就可以完美的觸發(fā)onLoad時(shí)間了,這里還有一個(gè)重點(diǎn)!就是van-list的父級(jí)也要定義一下高度,不然也是不行的!
至于業(yè)務(wù)一定要在settimeout中寫業(yè)務(wù)才能有效,了解的大佬看到了幫忙解釋一下,不是很明白
<div class="txtc" style="height: 100%; position: fixed; width: 100%"> <van-list style="height:100%;width:100%;overflow-y:auto;" v-model="loading" :finished="finished" finished-text="沒(méi)有更多了" @load="onLoad" > <div class="divinfo" v-for="item in tableData" :key="item.sid"></div> </van-list> </div>
vant中van-list的使用
van-list里面的元素不能有float樣式,否則會(huì)連續(xù)觸發(fā) load 事件
原代碼
<template> ? <div class="about"> ? ? <van-tabs v-model="active" sticky @change="getTypeDate"> ? ? ? <van-tab v-for="(tab) in typeList" :title="tab.name" :key="tab.id"> ? ? ? ? <div :style="{height: contentHeight}" class="pic-content"> ? ? ? ? ? <van-list ? ? ? ? ? ? :finished="finished" ? ? ? ? ? ? :finished-text="finishedText" ? ? ? ? ? ? v-model="loading" ? ? ? ? ? ? :offset="10" ? ? ? ? ? ? :immediate-check="false" ? ? ? ? ? ? @load="getserviceList" ? ? ? ? ? > ? ? ? ? ? <!------------------------------------------------- 修改前代碼 ---------------------------------------------> ? ? ? ? ? ? ? /*<div ? ? ? ? ? ? ? ? class="pic-box" ? ? ? ? ? ? ? ? v-for="(serve) in serviceList" ? ? ? ? ? ? ? ? :key="serve.id" ? ? ? ? ? ? ? ? @click="router(serve)" ? ? ? ? ? ? ? > ? ? ? ? ? ? ? ? <div class="pic-item"> ? ? ? ? ? ? ? ? ? <img ? ? ? ? ? ? ? ? ? ? v-if="serve.picturePath" ? ? ? ? ? ? ? ? ? ? :src="$BASE_PICTUREPATH_URL + serve.picturePath.split(',')[0]" ? ? ? ? ? ? ? ? ? > ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? ? ? <p>{{serve.name}}</p> ? ? ? ? ? ? ? ? <p class="price-red">¥{{serve.price}}</p> ? ? ? ? ? ? ? </div>*/ ? ? ? ? ? ? ? <!------------------------------------------------- 修改前代碼 ---------------------------------------------> ? ? ? ? ? </van-list> ? ? ? ? </div> ? ? ? </van-tab> ? ? </van-tabs> ? </div> </template>
<script> import { Tab, Tabs, List, Cell, Row, Col } from "vant"; import { FetchServeType, FetchServeList } from "../apis/serve.js"; export default { ? data() { ? ? return { ? ? ? active: 0, ? ? ? typeList: [], ? ? ? serviceList: [], ? ? ? type: "", ? ? ? finishedText: "", ? ? ? finished: false, ? ? ? pageNum: 1, ? ? ? pageSize: 10, ? ? ? contentHeight: 0, ? ? ? loading: false ? ? }; ? }, ? mounted() { ? ? this.getOrderStyle(); ? ? this.contentHeight = document.documentElement.clientHeight - 66 - 40 + "px"; ? }, ? methods: { ? ? async getOrderStyle() { ? ? ? let res = await FetchServeType(); ? ? ? if (res.data && res.data.success) { ? ? ? ? this.typeList = res.data.data; ? ? ? ? this.type = res.data.data[0].name; ? ? ? ? this.getTypeDate(); ? ? ? } ? ? }, ? ? getTypeDate() { ? ? ? this.pageNum = 1; ? ? ? this.type = this.typeList[this.active].name; ? ? ? this.serviceList = []; ? ? ? this.finishedText = ""; ? ? ? this.finished = false; ? ? ? this.getserviceList(); ? ? }, ? ? async getserviceList() { ? ? ? let toast = this.$toast.loading({ ? ? ? ? mask: true, ? ? ? ? message: "加載中..." ? ? ? }); ? ? ? const { type, pageNum, pageSize } = this; ? ? ? let params = { ? ? ? ? type, ? ? ? ? pageNum, ? ? ? ? pageSize ? ? ? }; ? ? ? let res = await FetchServeList(params); ? ? ? this.loading = false; ? ? ? toast.close(); ? ? ? if (res.data && res.data.success) { ? ? ? ? let list = (res.data.data && res.data.data.list) || []; ? ? ? ? if (pageNum > 1) { ? ? ? ? ? this.serviceList = [...this.serviceList, ...list]; ? ? ? ? } else { ? ? ? ? ? this.serviceList = list; ? ? ? ? } ? ? ? ? // 如果當(dāng)前頁(yè)數(shù) = 總頁(yè)數(shù),則已經(jīng)沒(méi)有數(shù)據(jù) ? ? ? ? if (res.data.data.pageNum === res.data.data.pages) { ? ? ? ? ? this.finished = true; ? ? ? ? ? this.finishedText = "- 沒(méi)有更多了-"; ? ? ? ? } ? ? ? ? // 如果總頁(yè)數(shù)大于當(dāng)前頁(yè)碼,頁(yè)碼+1 ? ? ? ? if (res.data.data.pages > pageNum) { ? ? ? ? ? this.pageNum++; ? ? ? ? } ? ? ? } ? ? ? console.log("FetchServeList: ", this.serviceList); ? ? } ? } }; </script>
<style lang="scss" scoped> .pic-content { ? overflow-y: scroll; ? -webkit-overflow-scrolling: touch; ? .pic-box { ? /****************************修改前代碼***************************/ ? ? background-color: #fff; ? ? overflow: hidden; ? ? break-inside: avoid; ? ? box-sizing: border-box; ? ? margin-bottom: 0.7rem; ? ? padding: 0.8rem; ? ? width: 48%; ? ? height: 16rem; ? ? ~~float: left;~~ /**************不能有float樣式*************/ ? ? margin: 1%; ? ? border-radius: 4px; ? ? ?/****************************修改前代碼***************************/ ? ? p:nth-of-type(1) { ? ? ? padding: 0.8rem 0; ? ? } ? ? p:nth-of-type(2) { ? ? ? color: red; ? ? } ? ? .pic-item { ? ? ? height: 11rem; ? ? ? flex-direction: column; ? ? ? justify-content: center; ? ? ? overflow: hidden; ? ? ? img { ? ? ? ? width: 100%; ? ? ? ? height: auto; ? ? ? ? border-radius: 4px; ? ? ? } ? ? } ? } } </style>
// 修改后代碼(注釋部分為修改后代碼)
<template> ? <div class="about"> ? ? <van-tabs v-model="active" sticky @change="getTypeDate"> ? ? ? <van-tab v-for="(tab) in typeList" :title="tab.name" :key="tab.id"> ? ? ? ? <div :style="{height: contentHeight}" class="pic-content"> ? ? ? ? ? <van-list ? ? ? ? ? ? :finished="finished" ? ? ? ? ? ? :finished-text="finishedText" ? ? ? ? ? ? v-model="loading" ? ? ? ? ? ? :offset="10" ? ? ? ? ? ? :immediate-check="false" ? ? ? ? ? ? @load="getserviceList" ? ? ? ? ? > ? ? ? ? ? <!------------------------------------------------- 修改后代碼 ---------------------------------------------> ? ? ? ? ? ? /*<van-row> ? ? ? ? ? ? ? <van-col ? ? ? ? ? ? ? ? span="12" ? ? ? ? ? ? ? ? class="pic-box" ? ? ? ? ? ? ? ? v-for="(serve) in serviceList" ? ? ? ? ? ? ? ? :key="serve.id" ? ? ? ? ? ? ? ? @click="router(serve)" ? ? ? ? ? ? ? > ? ? ? ? ? ? ? ? <div class="pic-item"> ? ? ? ? ? ? ? ? ? <img ? ? ? ? ? ? ? ? ? ? v-if="serve.picturePath" ? ? ? ? ? ? ? ? ? ? :src="$BASE_PICTUREPATH_URL + serve.picturePath.split(',')[0]" ? ? ? ? ? ? ? ? ? > ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? ? ? <p>{{serve.name}}</p> ? ? ? ? ? ? ? ? <p class="price-red">¥{{serve.price}}</p> ? ? ? ? ? ? ? </van-col> ? ? ? ? ? ? </van-row>*/ ? ? ? ? ? ? <!------------------------------------------------- 修改后代碼 ---------------------------------------------> ? ? ? ? ? </van-list> ? ? ? ? </div> ? ? ? </van-tab> ? ? </van-tabs> ? </div> </template>
<script> import { Tab, Tabs, List, Cell, Row, Col } from "vant"; import { FetchServeType, FetchServeList } from "../apis/serve.js"; export default { ? data() { ? ? return { ? ? ? active: 0, ? ? ? typeList: [], ? ? ? serviceList: [], ? ? ? type: "", ? ? ? finishedText: "", ? ? ? finished: false, ? ? ? pageNum: 1, ? ? ? pageSize: 10, ? ? ? contentHeight: 0, ? ? ? loading: false ? ? }; ? }, ? mounted() { ? ? this.getOrderStyle(); ? ? this.contentHeight = document.documentElement.clientHeight - 66 - 40 + "px"; ? }, ? methods: { ? ? async getOrderStyle() { ? ? ? let res = await FetchServeType(); ? ? ? if (res.data && res.data.success) { ? ? ? ? this.typeList = res.data.data; ? ? ? ? this.type = res.data.data[0].name; ? ? ? ? this.getTypeDate(); ? ? ? } ? ? }, ? ? getTypeDate() { ? ? ? this.pageNum = 1; ? ? ? this.type = this.typeList[this.active].name; ? ? ? this.serviceList = []; ? ? ? this.finishedText = ""; ? ? ? this.finished = false; ? ? ? this.getserviceList(); ? ? }, ? ? async getserviceList() { ? ? ? let toast = this.$toast.loading({ ? ? ? ? mask: true, ? ? ? ? message: "加載中..." ? ? ? }); ? ? ? const { type, pageNum, pageSize } = this; ? ? ? let params = { ? ? ? ? type, ? ? ? ? pageNum, ? ? ? ? pageSize ? ? ? }; ? ? ? let res = await FetchServeList(params); ? ? ? this.loading = false; ? ? ? toast.close(); ? ? ? if (res.data && res.data.success) { ? ? ? ? let list = (res.data.data && res.data.data.list) || []; ? ? ? ? if (pageNum > 1) { ? ? ? ? ? this.serviceList = [...this.serviceList, ...list]; ? ? ? ? } else { ? ? ? ? ? this.serviceList = list; ? ? ? ? } ? ? ? ? // 如果當(dāng)前頁(yè)數(shù) = 總頁(yè)數(shù),則已經(jīng)沒(méi)有數(shù)據(jù) ? ? ? ? if (res.data.data.pageNum === res.data.data.pages) { ? ? ? ? ? this.finished = true; ? ? ? ? ? this.finishedText = "- 沒(méi)有更多了-"; ? ? ? ? } ? ? ? ? // 如果總頁(yè)數(shù)大于當(dāng)前頁(yè)碼,頁(yè)碼+1 ? ? ? ? if (res.data.data.pages > pageNum) { ? ? ? ? ? this.pageNum++; ? ? ? ? } ? ? ? } ? ? ? console.log("FetchServeList: ", this.serviceList); ? ? } ? } }; </script>
<style lang="scss" scoped> .pic-content { ? overflow-y: scroll; ? -webkit-overflow-scrolling: touch; ? .pic-box { ? /************************ 修改后代碼**************************/ ? ?background-color: #fff; ? ? overflow: hidden; ? ? box-sizing: border-box; ? ? margin-bottom: 0.7rem; ? ? padding: 0.8rem; ? ? height: 16rem; ? ? border-radius: 4px; ? ? /************************ 修改后代碼************************ **/ ? ? p:nth-of-type(1) { ? ? ? padding: 0.8rem 0; ? ? } ? ? p:nth-of-type(2) { ? ? ? color: red; ? ? } ? ? .pic-item { ? ? ? height: 11rem; ? ? ? flex-direction: column; ? ? ? justify-content: center; ? ? ? overflow: hidden; ? ? ? img { ? ? ? ? width: 100%; ? ? ? ? height: auto; ? ? ? ? border-radius: 4px; ? ? ? } ? ? } ? } } </style>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue+Minio實(shí)現(xiàn)多文件進(jìn)度上傳的詳細(xì)步驟
這篇文章主要給大家介紹了關(guān)于如何利用vue+Minio實(shí)現(xiàn)多文件進(jìn)度上傳的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-03-03前端文件導(dǎo)出設(shè)置responseType為blob時(shí)遇到的問(wèn)題及解決
這篇文章主要給大家介紹了關(guān)于前端文件導(dǎo)出設(shè)置responseType為blob時(shí)遇到的問(wèn)題及解決方法,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09vue在自定義組件中使用v-model進(jìn)行數(shù)據(jù)綁定的方法
這篇文章主要介紹了vue在自定義組件中使用v-model進(jìn)行數(shù)據(jù)綁定的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03vue使用router-view調(diào)用頁(yè)面方式
這篇文章主要介紹了vue使用router-view調(diào)用頁(yè)面方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03淺談vue中改elementUI默認(rèn)樣式引發(fā)的static與assets的區(qū)別
下面小編就為大家分享一篇淺談vue中改elementUI默認(rèn)樣式引發(fā)的static 與assets的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02Vue引用Swiper4插件無(wú)法重寫分頁(yè)器樣式的解決方法
今天小編就為大家分享一篇Vue引用Swiper4插件無(wú)法重寫分頁(yè)器樣式的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Vue+axios使用FormData方式向后端發(fā)送數(shù)據(jù)
在前后端分離的項(xiàng)目中經(jīng)常使用到Vue+axios通過(guò)FormData的方式向后端發(fā)送表單數(shù)據(jù),下面就來(lái)介紹一下如何實(shí)現(xiàn),感興趣的可以了解一下2023-09-09