首页IT科技封装表单组件vue(记录–这样封装列表 hooks,一天可以开发 20 个页面)

封装表单组件vue(记录–这样封装列表 hooks,一天可以开发 20 个页面)

时间2025-06-20 21:32:31分类IT科技浏览3999
导读:这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助...

这里给大家分享我在网上总结出来的一些知识            ,希望对大家有所帮助

这样                     ,我们就完成了一个基本的列表需求的逻辑部分            。大部分的列表需求都是类似的逻辑      ,既然如此         ,Dont 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

如果对您有所帮助               ,欢迎您点个关注                     ,我会定时更新技术文档   ,大家一起讨论学习            ,一起进步      。

声明:本站所有文章                     ,如无特殊说明或标注      ,均为本站原创发布                    。任何个人或组织         ,在未征得本站同意时                     ,禁止复制                     、盗用      、采集         、发布本站内容到任何网站                     、书籍等各类媒体平台              。如若本站内容侵犯了原著者的合法权益          ,可联系我们进行处理   。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
家里可以干的副业(家里什么赚钱-失业的我呆在家中充满着焦虑,梦想有一天能坐在家中也有收入来源)