最新要闻
- 光线传媒回应股价暴跌:节前涨过一波 公司主投的《深海》票房不及预期
- 世界观天下!庆祝中国新年!梅西东家巴黎全队球员身穿中文球衣出战
- 焦点速读:4人修改游戏源代码 架设私服 2年牟利260余万元
- 全球实时:因堵车错过高速免费时段要缴1000多过路费 有司机不干了:网友支招
- 世界热头条丨郭明錤:苹果或明年推出折叠屏iPad 配备碳纤维支架
- 焦点信息:ChatGPT很厉害 但还有关键问题悬而未决
- 世界简讯:夫妻过年捡烟花纸壳7天捡5000斤赚500元:网友五味杂陈
- 环球快消息!注意了!22岁女生熬夜关灯玩手机致霰粒肿:做了手术才解决
- 长城“铁娘子”王凤英出任小鹏汽车总裁 向何小鹏汇报
- 焦点快报!跌破0.5元:阿里健康大药房劲度N95口罩0.49元/片(独立包装)
- 实时:背大锅!调查称三成离婚与一方沉迷手机有关
- 当前时讯:制作成本不超一千万、抄袭等争议不断!《满江红》:追究到底 还原真相
- 全球热头条丨惨剧再现 母子俩大年初一家中围炉煮茶身亡:一氧化碳中毒
- 《魔兽世界》国服停止 暴雪激怒中国玩家态度傲慢!中消协发声
- 每日视点!《狂飙》演员演出前才知道自己真实身份 导演太会玩
- 世界热消息:《满江红》7天营收7千万也带不动 光线传媒股价暴跌
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
记录--这样封装列表 hooks,一天可以开发 20 个页面
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
这样封装列表 hooks,一天可以开发 20 个页面
前言
在做移动端的需求时,我们经常会开发一些列表页,这些列表页大多数有着相似的功能:分页获取列表、上拉加载、下拉刷新···
【资料图】
在 Vue
出来 compositionAPI
之前,我们想要复用这样的逻辑还是比较麻烦的,好在现在 Vue2.7+
都支持 compositionAPI
语法了,这篇文章我将 手把手
带你用 compositionAPI
封装一个名为 useList
的 hooks
来实现列表页的逻辑复用。
基础版
需求分析
一个列表,最基本的需求应该包括: 发起请求,获取到列表的数组,然后将该数组渲染成相应的 DOM
节点。要实现这个功能,我们需要以下变量:
- list : 数组变量,用来存放后端返回的数据,并在
template
模板中使用v-for
来遍历渲染成我们想要的样子。 - listReq: 发起 http 请求的函数,一般是
axios
的实例
代码实现
有了上面的分析,我们可以很轻松地在 setup
中写出如下代码:
import { ref } from "vue"import axios from "axios" // 简单示例,就不给出封装axios的代码了const list = ref([])const listReq = () => { axios.get("/url/to/getList").then((res) => { list.value = res.list })}listReq()
这样,我们就完成了一个基本的列表需求的逻辑部分。大部分的列表需求都是类似的逻辑,既然如此,Don"t Repeat Yourself!
(不要重复写你的代码!),我们来把它封装成通用的方法:
- 首先,既然是通用的,会在多个地方使用,那么数据肯定不能乱了,我们要在每次使用
useList
的时候都拿到独属于自己的那一份数据。是不是感觉很熟悉?对的,就是以前的data为什么是一个函数
那个问题!所以我们的useList
是需要导出一个函数,我们从这个函数中获取数据与方法。让这个函数导出一个对象/数组,这样调用的时候解构
就可以拿到我们需要的变量和方法了
// useList.js 中const useList = () => { // 待补充的函数体 return {}}export default useList
- 然后,不同的地方调用的接口肯定不一样,我们想一次封装,不再维护,那么咱们干脆在使用的时候,把调用接口的方法传进来就可以了
// useList.js 中import { ref } from "vue"const useList = (listReq) => { if (!listReq) { return new Error("请传入接口调用方法!") } const list = ref([]) const getList = () => { listReq().then((res) => (list.value = res.list)) } return { list, getList, }}export default useList
这样,我们就完成了一个简单的列表hooks
,使用的时候直接:
// setup中import useList from "@/utils"const { list, getList } = useList(axios.get("url/to/get/list"))getList()
等等!列表好像不涉及到DOM
操作,那咱们再偷点懒,直接在useList
内部就调用了吧!
// useList.js中import { ref } from "vue"const useList = (listReq) => { if (!listReq) { return new Error("请传入接口调用方法!") } const list = ref([]) const getList = () => { listReq().then((res) => (list.value = res.list)) } getList() // 直接初始化,省去在外面初始化的步骤 return { list, getList, }}export default useList
这时有老哥要说了,那我要是一个页面有多个列表怎么办?嘿嘿,别忘了,解构的时候是可以重命名的
// setup中const { list: goodsList, getList: getGoodsList } = useList( axios.get("/url/get/goods"))const { list: recommendList, getList: getRecommendList } = useList( axios.get("/url/get/goods"))
这样,我们就同时在一个页面里面,获取到了商品列表以及推荐列表所需要的变量与方法啦
带分页版
如果数据量比较大的话,所有的数据全部拿出来渲染显然不合理,所以我们一般要进行分页处理,我们来分析一下这个需求:
需求分析
- 要分页,那咱们肯定要告诉后端当前请求的是第几页、每页多少条,可能有些地方还需要展示总共有多少条,为了方便管理,咱们把这些分页数据统一放到
pageInfo对象中
- 分页了,那咱们肯定还有加载下一页的需求,需要一个
loadmore
函数 - 分页了,那咱们肯定还会有刷新的需求,需要一个
initList
函数
代码实现
需求分析好了,代码实现起来就简单了,废话少说,上代码!
// useList.js中import { ref } from "vue"const useList = (listReq) => { if (!listReq) { return new Error("请传入接口调用方法!") } const list = ref([]) // 新增pageInfo对象保存分页数据 const pageInfo = ref({ pageNum: 1, pageSize: 10, total: 0, }) const getList = () => { // 分页数据作为参数传递给接口调用函数即可 // 将请求这个Promise返回出去,以便链式then return listReq(pageInfo.value).then((res) => { list.value = res.list // 更新总数量 pageInfo.value.total = res.total // 返回出去,交给then默认的Promise,以便后续使用 return res }) } // 新增加载下一页的函数 const loadmore = () => { // 下一页,那咱们把当前页自增一下就行了 pageInfo.value.pageNum += 1 // 如果已经是最后一页了(本次获取到空数组) getList().then((res) => { if (!res.list.length) { uni.showToast({ title: "没有更多了", icon: "none", }) } }) } // 新增初始化 const initList = () => { // 初始化一般是要把所有的查询条件都初始化,这里只有分页,咱就回到第一页就行 pageInfo.value.pageNum = 1 getList() } getList() return { list, getList, loadmore, initList, }}export default useList
完工!跑起来试试,Perfec......等等,好像不太对...
加载更多,应该是把两次请求的数据合并到一起渲染出来才对,这怎么直接替换掉了?
回头看看代码,原来是咱们漏了拼接的逻辑,补上,补上
// useList.js中// ...省略其余代码const getList = () => { // 分页数据作为参数传递给接口调用函数即可 return listReq(pageInfo.value).then((res) => { // 当前页不为1则是加载更多,需要拼接数据 if (pageInfo.value.pageNum === 1) { list.value = res.list } else { list.value = [...list.value, ...res.list] } pageInfo.value.total = res.total return res })}// ...省略其余代码
带 hooks 版
上面的分页版,我们给出了 加载更多
和 初始化列表
功能,但是还是要手动调用。仔细想想,咱们刷新列表,一般都是在页面顶部下拉的时候刷新的;而加载更多,一般都是在滚动到底部的时候加载的。既然都是一样的触发时机,那咱们继续封装吧!
需求分析
- uni-app 中提供了
onPullDownRefresh
和onReachBottom
钩子,在其中处理相关逻辑即可 - 有些列表可能不是在页面中,而是在
scroll-view
中,还是需要手动处理,因此上面的函数咱们依然需要导出
代码实现
钩子函数(hooks)接受一个回调函数作为参数,咱们直接把上面的函数传入即可
需要注意的是,uni-app 中,下拉刷新的动画需要手动关闭,咱们还需要改造一下 listReq
函数
// useList中import { onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app"// ...省略其余代码onPullDownRefresh(initList)onReachBottom(loadmore)const getList = () => { // 分页数据作为参数传递给接口调用函数即可 return listReq(pageInfo.value) .then((res) => { // ...省略其余代码 }) .finally((info) => { // 不管成功还是失败,关闭下拉刷新的动画 uni.stopPullDownRefresh() // 在最后再把前面返回的消息return出去,以便后续处理 return info })}// ...省略其余代码
带参数
其实在实际开发中,我们在发起请求时可能还需要其他的参数,上面我们都是固定的只有分页的参数,可以稍加改造
需求分析
可能大家第一反应是多一个参数,或者用 展开运算符 (...)再定义一个形参就行了。这么做肯定是没问题的,不过在这里的话不够优雅~
我们这里是要增加一个传给后端的参数,一般都是一起以 JSON 对象的形式传过去,既然如此,那咱们把所有的参数都用一个对象接受,发起请求的时候和分页参数对象合并为一个对象,代码的可读性会更高,使用者在使用时也可以自由地定义 key-value
键值对
代码实现
// useList中const useList = (listReq, data) => { // ...省略其余代码 // 判断第二个参数是否是对象,以免后面使用展开运算符时报错 if (data && Object.prototype.toString.call(data) !== "[object Object]") { return new Error("额外参数请使用对象传入") } const getList = () => { const params = { ...pageInfo.value, ...data, } return listReq(params).then((res) => { // ...省略其余代码 }) } // ...省略其余代码}// ...省略其余代码
带默认配置版
有些时候我们的列表是在页面中间,不需要触底加载更多;有时候我们可能需要在不同的地方调用相同的接口,但是需要获取的数据量不一样....
为了适应各种各样的需求,我们可以稍加改造,添加一个带有默认值的配置对象,
// useList.js中const defaultConfig = { pageSize: 10, // 每页数量,其实也可以在data里面覆盖 needLoadMore: true, // 是否需要下拉加载 data: {}, // 这个就是给接口用的额外参数了 // 还可以根据自己项目需求添加其他配置}// 添加一个有默认值的参数,依然满足大部分列表页传入接口即可使用的需求const useList = (listReq, config = defaultConfig) => { // 解构的时候赋上初始值,这样即使配置参数只传了一个参数,也不影响其他的配置 const { pageSize = defaultConfig.pageSize, needLoadMore = defaultConfig.needLoadMore, data = defaultConfig.data, } = config // 应用相应的配置 if (needLoadMore) { onReachBottom(loadmore) } const pageInfo = ref({ pageNum: 1, pageSize, total: 0, }) // ...省略其余代码}// ...省略其余代码
这样一来,咱们就实现了一个满足大部分移动端列表页的逻辑复用 hooks
web 端的几乎只有加载更多(翻页)的时候逻辑不太一样,不需要拼接数据,在封装的时候可以把分页器的处理逻辑一起封装进来
本文转载于:
https://juejin.cn/post/7165467345648320520
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
-
焦点热门:如何根据网络位计算主机位的数量
20--4096 21--2048 22--1024 23--512 包含两个24位子网掩码的网络地址 24--256 25--128 26--64 2
来源: 记录--这样封装列表 hooks,一天可以开发 20 个页面
焦点热门:如何根据网络位计算主机位的数量
光线传媒回应股价暴跌:节前涨过一波 公司主投的《深海》票房不及预期
世界观天下!庆祝中国新年!梅西东家巴黎全队球员身穿中文球衣出战
焦点速读:4人修改游戏源代码 架设私服 2年牟利260余万元
全球实时:因堵车错过高速免费时段要缴1000多过路费 有司机不干了:网友支招
世界热头条丨郭明錤:苹果或明年推出折叠屏iPad 配备碳纤维支架
字典树学习笔记
世界百事通!2023考研资料整合推荐
看点:为什么要进行网络分层
焦点信息:ChatGPT很厉害 但还有关键问题悬而未决
世界简讯:夫妻过年捡烟花纸壳7天捡5000斤赚500元:网友五味杂陈
环球快消息!注意了!22岁女生熬夜关灯玩手机致霰粒肿:做了手术才解决
长城“铁娘子”王凤英出任小鹏汽车总裁 向何小鹏汇报
焦点快报!跌破0.5元:阿里健康大药房劲度N95口罩0.49元/片(独立包装)
欧拉函数
【天天报资讯】什么是以太网
天天观天下!Docker数据管理
实时:背大锅!调查称三成离婚与一方沉迷手机有关
当前时讯:制作成本不超一千万、抄袭等争议不断!《满江红》:追究到底 还原真相
全球焦点!Nginx 前端部署配置
全球热头条丨惨剧再现 母子俩大年初一家中围炉煮茶身亡:一氧化碳中毒
《魔兽世界》国服停止 暴雪激怒中国玩家态度傲慢!中消协发声
每日视点!《狂飙》演员演出前才知道自己真实身份 导演太会玩
世界热消息:《满江红》7天营收7千万也带不动 光线传媒股价暴跌
世界最资讯丨博主曝吉利品牌2023年产品及渠道规划:领克改直营、血拼插混
Yarn平滑下线节点(Graceful Decommission)
【天天热闻】火山引擎 DataTester:“在字节,A/B 实验是一种信仰”
Asp.Net7 与 Vue3 组成的 BFF模式
属实赚麻了!《满江红》7天为光线传媒创收7000万元
大赚718亿元!网红基金经理张坤、葛兰火速回血
【全球聚看点】2022年各国汽车销量榜:中国第一 印度迅猛崛起
世界速讯:端劳饭碗 中国研发出玉米秸秆合成淀粉及蛋白技术:成本大降
THAILAND是哪个国家?thailand怎么读英语?
职务怎么填?职务侵占罪立案标准
奋进的旋律大结局是什么?奋进的旋律演员表名单
春风徐徐下一句的是什么?春风徐徐打一生肖是什么?
立春节气的特点和风俗有哪些?立春节气朋友圈句子
谷歌浏览器怎么样?谷歌浏览器无法打开网页是什么原因?
地暖怎么进行打压试验?地暖是怎么样供暖的?
LOL裁决之镰怎么解除?lol裁决之镰为什么没了?
《安富莱嵌入式周报》第301期:ThreadX老大离开微软推出PX5 RTOS第5代系统,支持回流焊的自焊接PCB板设计,单色屏实现多级灰度播放视频效果
【全球新要闻】河北小伙深耕OI默默无闻 LOGO设计放眼全球一鸣惊人 当LOGO设计与世界文化擦出火花——JJQ的LOGO设计之路(纯文
MOTO XT390手机什么时候上市的?MOTO XT390手机参数
iPhone5C上市价格是多少?iphone5c还能用微信吗?
当前头条:德系车在中国不香了?2022年大众、BBA少卖了20万台
《满江红》:成也算计 败也算计
【焦点热闻】轻至689克!富士通推出UH-X/H1轻薄本:世界上最轻的14英寸笔电
环球快播:给头发做个香氛SPA:舒蕾山茶花洗发水500ml 19.9元/瓶大促
报道:特斯拉全球开打价格战 大众第一个交枪!CEO:我们不跟
ServletContext与静态变量(static)的区别,数据库连接池放在哪里
最新资讯:Fortran数组排序:冒泡排序法
头条焦点:Python Numpy 中的打印设置函数set_printoptions
环球播报:小米汽车全身照传疯了!轿跑车身+迈凯伦式大灯 网友:保里保气
领90元大额券:可孚全自动血压计49.9元到手 给爸妈买一台
【全球快播报】真正开对撞机的女孩:从不化妆 一守就是13年
当前速看:苹果车祸检测功能误报不断 救援部门被折腾惨了
新消息丨可直接丢进马桶里!德祐湿厕纸大促:3包不到16元
【世界快播报】读Java8函数式编程笔记05_数据并行化
每日热门:首次打破日本垄断 国内量产OLED显示屏关键材料FMM
每日热文:小米MIUI 14最新升级计划出炉:小米11、Redmi K40等25款机型在列
天天要闻:《满江红》票房近32亿 大V称制作成本不超一千万:官方已无视造谣者
世界信息:真实感渲染:模型变换
码龄几十年的老程序员都不知道的存图小技巧“指向立体星” 学到就是赚到!速戳>>
【全球独家】微信春节大数据出炉:发送红包40亿次 《三体》阅读量第一
你想坐吗?国产大飞机C919航班定了:2月28日北京上海首航
天天即时看!CPU核心数越多越好?看懂CPU核心线程数才能不被骗
全球热点![概率论与数理统计]笔记:5.2 参数的最大似然估计与矩估计
Exgcd(扩展欧几里得算法)
【全球报资讯】滑铁卢?《流浪地球2》北美上映票房不敌印度电影
热门看点:ChatGPT爆火:谷歌、Meta等压力大
微资讯!男子把绿动车当成绿皮车抽烟被拘:其实是“绿巨人”电力动车组
当前速看:状告4位大V后 《满江红》片方称不再起诉其他造谣者:不再回应
装饰模式
全球热头条丨漫威宇宙十大战力英雄:钢铁侠仅排第五
【世界新要闻】Intel花六个月造了一块乐高Arc显卡:1比1完美复刻!
环球资讯:【byob】 payload 生成过程
每日时讯![概率论与数理统计]笔记:5.1 点估计概述
热议:VMware vSphere ESXi 7.0安装配置
天天热点评!QPython实例01-获取所有短信并生成词云
世界观点:微信:2023年春节用户发红包超40亿次 竖屏春晚超1.9亿人观看
世界微动态丨Uzi再被冻结43万股权!公司与范丞丞合作
Blazor模式讲解
全球信息:国补退坡 上海延续新能源车置换补贴:单车补1万元
【全球时快讯】米哈游全新力作!《崩坏:星穹铁道》全平台预约已突破千万
今日热门!富豪刘銮雄拍卖76只爱马仕包:最贵一只200万
【全球时快讯】算法对算法!斯坦福大学推出DetectGPT:阻止学生用AI写作业
今日观点!2月2日或能肉眼看见5万年一遇的绿色彗星:正迅速逼近地球!
焦点资讯:Kubernetes监控手册06-监控APIServer
全球最资讯丨CRT&EXCRT(中国剩余定理和扩展中国剩余定理)
【新视野】学习笔记——redis事务、乐观锁、悲观锁
国内首家!统信操作系统成功获得商用密码产品认证证书
环球热点!“流浪地球”成功的概率有多高?你肯定想不到
当前视点!脑洞大开的机械键盘 内部竟搭CPU和GPU
天天百事通!阿里云推全国首个跨省域智慧大脑:汇聚江浙沪242项数据资源
全球资讯:不得不防!奥密克戎新变异毒株“双头犬”现身美国:已被世卫监测
【环球热闻】记录--Vue PC前端扫码登录
[概率论与数理统计]笔记:4.4 抽样分布
当前速讯:1.29数论课笔记
最新快讯!40万级乱杀!全新国产奔驰GLC配置曝光:四款车型、两种外观