使用Vant框架list组件遇到的坑及解决

Meta ·
更新时间:2024-11-13
· 985 次阅读

目录

使用Vant框架list组件的坑

介绍

特性

聊一下使用list组件遇到的坑

vant中van-list的使用

原代码

使用Vant框架list组件的坑 介绍

Vant 是有赞前端团队开源的移动端组件库,于 2017 年开源,已持续维护 4 年时间。

Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一。

特性

提供 60 多个高质量组件,覆盖移动端各类场景

性能极佳,组件平均体积不到 1kb(min+gzip)

单元测试覆盖率 90%+,提供稳定性保障

完善的中英文文档和示例

支持 Vue 2 & Vue 3

支持按需引入

支持主题定制

支持国际化

支持 TypeScript

支持 SSR

快速配置和具体介绍请去官方文档,Vant框架在Github上点赞众多,用起来发现还是很好用的,强力推荐

聊一下使用list组件遇到的坑

官方文档的实例代码是这样的:

<van-list v-model="loading" :finished="finished" finished-text="没有更多了" @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() { // 异步更新数据 // setTimeout 仅做示例,真实场景中一般为 ajax 请求 setTimeout(() => { for (let i = 0; i < 10; i++) { this.list.push(this.list.length + 1); } // 加载状态结束 this.loading = false; // 数据全部加载完成 if (this.list.length >= 40) { this.finished = true; } }, 1000); }, }, };

效果图片:

可是!你,发现,发现完全不好用!这个定时任务简直看不懂,触底加载简直毫无逻辑,通过几个小时的研究,发现问题所在居然是CSS!对,你没有听错!是CSS导致的!

下方代码,重点看css部分,JS部分,记住settimeout不要去掉,不要相信他的注释,业务写在settimeout里就可以了

解释一下这个css的含义,就是van-list需要给他定义一个高度,并且滚动自适应,这样在不填满高度或者是滚动触底的时候就可以完美的触发onLoad时间了,这里还有一个重点!就是van-list的父级也要定义一下高度,不然也是不行的!

至于业务一定要在settimeout中写业务才能有效,了解的大佬看到了帮忙解释一下,不是很明白

<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="没有更多了" @load="onLoad" > <div class="divinfo" v-for="item in tableData" :key="item.sid"></div> </van-list> </div> vant中van-list的使用

van-list里面的元素不能有float样式,否则会连续触发 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;         }         // 如果当前页数 = 总页数,则已经没有数据         if (res.data.data.pageNum === res.data.data.pages) {           this.finished = true;           this.finishedText = "- 没有更多了-";         }         // 如果总页数大于当前页码,页码+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;         }         // 如果当前页数 = 总页数,则已经没有数据         if (res.data.data.pageNum === res.data.data.pages) {           this.finished = true;           this.finishedText = "- 没有更多了-";         }         // 如果总页数大于当前页码,页码+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>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。



list vant

需要 登录 后方可回复, 如果你还没有账号请 注册新账号