Vue3这样写列表页,让性能更好更高效!

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

Vue3这样写列表页,让性能更好更高效!

在开发管理后台过程中,一定会遇到不少了增删改查页面,而这些页面的逻辑大多都是相同的,这样子会导致代码耦合度越来越高,下面,我们将这些可复用的数据抽离出来成hook,既解决耦合度的问题又提高工作效率。

在开发管理后台过程中,一定会遇到不少了增删改查页面,而这些页面的逻辑大多都是相同的,如获取列表数据,分页,筛选功能这些基本功能。而不同的是呈现出来的数据项。还有一些操作按钮。【相关推荐:vuejs视频教程、web前端开发】

对于刚开始只有 1,2 个页面的时候大多数开发者可能会直接将之前的页面代码再拷贝多一份出来,而随着项目的推进类似页面数量可能会越来越多,这直接导致项目代码耦合度越来越高。

这也是为什么在项目中一些可复用的函数或组件要抽离出来的主要原因之一

下面,我们封装一个通用的useList,适配大多数增删改查的列表页面,让你更快更高效的完成任务,准点下班 ~

前置知识VueVue Composition Api封装

我们需要将一些通用的参数和函数抽离出来,封装成一个通用hook,后续在其他页面复用相同功能更加简单方便。

定义列表页面必不可少的分页数据
export default function useList() {  // 加载态  const loading = ref(false);  // 当前页  const curPage = ref(1);  // 总数量  const total = ref(0);  // 分页大小  const pageSize = ref(10);}
登录后复制如何获取列表数据

思考一番,让useList函数接收一个listRequestFn参数,用于请求列表中的数据。

定义一个list变量,用于存放网络请求回来的数据内容,由于在内部无法直接确定列表数据类型,通过泛型的方式让外部提供列表数据类型。

export default function useList<ItemType extends Object>(  listRequestFn: Function) {  // 忽略其他代码  const list = ref<ItemType[]>([]);}
登录后复制

useList中创建一个loadData函数,用于调用获取数据函数,该函数接收一个参数用于获取指定页数的数据(可选,默认为curPage的值)。

执行流程设置加载状态调用外部传入的函数,将获取到的数据赋值到listtotal中关闭加载态

这里使用了 async/await 语法,假设请求出错、解构出错情况会走 catch 代码块,再关闭加载态

这里需要注意,传入的 listRequestFn 函数接收的参数数量和类型是否正常对应上请根据实际情况进行调整

export default function useList<ItemType extends Object>(  listRequestFn: Function) {  // 忽略其他代码  // 数据  const list = ref<ItemType[]>([]);  // 过滤数据  // 获取列表数据  const loadData = async (page = curPage.value) => {    // 设置加载中    loading.value = true;    try {      const {        data,        meta: { total: count },      } = await listRequestFn(pageSize.value, page);      list.value = data;      total.value = count;    } catch (error) {      console.log("请求出错了", "error");    } finally {      // 关闭加载中      loading.value = false;    }  };}
登录后复制

别忘了,还有切换分页要处理

使用 watch 函数监听数据,当curPagepageSize的值发生改变时调用loadData函数获取新的数据。

export default function useList<ItemType extends Object>(  listRequestFn: Function) {  // 忽略其他代码  // 监听分页数据改变  watch([curPage, pageSize], () => {    loadData(curPage.value);  });}
登录后复制

现在实现了基本的列表数据获取

实现数据筛选器

在庞大的数据列表中,数据筛选是必不可少的功能

通常,我会将筛选条件字段定义在一个ref中,在请求时将ref丢到请求函数即可。

在 useList 函数中,第二个参数接收一个filterOption对象,对应列表中的筛选条件字段。

调整一下loadData函数,在请求函数中传入filterOption对象即可

注意,传入的 listRequestFn 函数接收的参数数量和类型是否正常对应上请根据实际情况进行调整

export default function useList<  ItemType extends Object,  FilterOption extends Object>(listRequestFn: Function, filterOption: Ref<Object>) {  const loadData = async (page = curPage.value) => {    // 设置加载中    loading.value = true;    try {      const {        data,        meta: { total: count },      } = await listRequestFn(pageSize.value, page, filterOption.value);      list.value = data;      total.value = count;    } catch (error) {      console.log("请求出错了", "error");    } finally {      // 关闭加载中      loading.value = false;    }  };}
登录后复制

注意,这里 filterOption 参数类型需要的是 ref 类型,否则会丢失响应式 无法正常工作

清空筛选器字段

在页面中,有一个重置的按钮,用于清空筛选条件。这个重复的动作可以交给 reset 函数处理。

通过使用 Reflect 将所有值设定为undefined,再重新请求一次数据。

什么是 Reflect?看看这一篇文章Reflect 映射对象

export default function useList<  ItemType extends Object,  FilterOption extends Object>(listRequestFn: Function, filterOption: Ref<Object>) {  const reset = () => {    if (!filterOption.value) return;    const keys = Reflect.ownKeys(filterOption.value);    filterOption.value = {} as FilterOption;    keys.forEach((key) => {      Reflect.set(filterOption.value!, key, undefined);    });    loadData();  };}
登录后复制导出功能

除了对数据的查看,有些界面还需要有导出数据功能(例如导出 csv,excel 文件),我们也把导出功能写到useList

通常,导出功能是调用后端提供的导出Api获取一个文件下载地址,和loadData函数类似,从外部获取exportRequestFn函数来调用Api

在函数中,新增一个exportFile函数调用它。

export default function useList<  ItemType extends Object,  FilterOption extends Object>(  listRequestFn: Function,  filterOption: Ref<Object>,  exportRequestFn?: Function) {  // 忽略其他代码  const exportFile = async () => {    if (!exportRequestFn) {      throw new Error("当前没有提供exportRequestFn函数");    }    if (typeof exportRequestFn !== "function") {      throw new Error("exportRequestFn必须是一个函数");    }    try {      const {        data: { link },      } = await exportRequestFn(filterOption.value);      window.open(link);    } catch (error) {      console.log("导出失败", "error");    }  };}
登录后复制

注意,传入的 exportRequestFn 函数接收的参数数量和类型是否正常对应上请根据实际情况进行调整

优化

现在,整个useList已经满足了页面上的需求了,拥有了获取数据,筛选数据,导出数据,分页功能

还有一些细节方面,在上面所有代码中的try..catch中的catch代码片段并没有做任何的处理,只是简单的console.log一下

提供钩子

useList新增一个 Options 对象参数,用于函数成功、失败时执行指定钩子函数与输出消息内容。

定义 Options 类型
export interface MessageType {  GET_DATA_IF_FAILED?: string;  GET_DATA_IF_SUCCEED?: string;  EXPORT_DATA_IF_FAILED?: string;  EXPORT_DATA_IF_SUCCEED?: string;}export interface OptionsType {  requestError?: () => void;  requestSuccess?: () => void;  message: MessageType;}export default function useList<  ItemType extends Object,  FilterOption extends Object>(  listRequestFn: Function,  filterOption: Ref<Object>,  exportRequestFn?: Function,  options? :OptionsType) {  // ...}
登录后复制设置Options默认值
const DEFAULT_MESSAGE = {  GET_DATA_IF_FAILED: "获取列表数据失败",  EXPORT_DATA_IF_FAILED: "导出数据失败",};const DEFAULT_OPTIONS: OptionsType = {  message: DEFAULT_MESSAGE,};export default function useList<  ItemType extends Object,  FilterOption extends Object>(  listRequestFn: Function,  filterOption: Ref<Object>,  exportRequestFn?: Function,  options = DEFAULT_OPTIONS) {  // ...}
登录后复制

在没有传递钩子的情况霞,推荐设置默认的失败时信息显示

优化loadDataexportFile函数

基于 elementui 封装 message 方法

import { ElMessage, MessageOptions } from "element-plus";export function message(message: string, option?: MessageOptions) {  ElMessage({ message, ...option });}export function warningMessage(message: string, option?: MessageOptions) {  ElMessage({ message, ...option, type: "warning" });}export function errorMessage(message: string, option?: MessageOptions) {  ElMessage({ message, ...option, type: "error" });}export function infoMessage(message: string, option?: MessageOptions) {  ElMessage({ message, ...option, type: "info" });}
登录后复制

loadData 函数

export default function useList<ItemType extends Object>(  listRequestFn: Function) {  // 忽略其他代码  const list = ref<ItemType[]>([]);}0
登录后复制

exportFile 函数

export default function useList<ItemType extends Object>(  listRequestFn: Function) {  // 忽略其他代码  const list = ref<ItemType[]>([]);}1
登录后复制useList 使用方法
export default function useList<ItemType extends Object>(  listRequestFn: Function) {  // 忽略其他代码  const list = ref<ItemType[]>([]);}2
登录后复制

本文useList的完整代码在 github.com/QC2168/snip…

(学习视频分享:vuejs入门教程、编程基础视频)

以上就是Vue3这样写列表页,让性能更好更高效!的详细内容,更多请关注9543建站博客其它相关文章!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:JavaScript数组reduce()方法使用实例
下一篇:uniapp注册成功后跳转怎么实现

发表评论

评论列表

2026-03-15 23:56:38

每天顶顶贴,一身轻松啊!https://s-wps.it.com

2026-03-16 08:21:16

看帖、回帖、拿分、走人https://www.pc-kuailian.it.com

2026-03-16 14:21:29

看了这么多帖子,第一次看到这么有深度了!https://www.mace-wps.cn

2026-03-16 21:00:02

被楼主的逻辑打败了!https://www.chrome-zh.it.com

2026-03-16 22:22:56

楼主看起来很有学问!https://cn-kuailian.it.com

2026-03-19 00:38:13

经典,收藏了!https://www.youdao-fanyi.it.com

2026-03-19 12:49:42

楼上的真不讲道理!https://www.a-google.com

2026-03-19 14:39:01

求加**!https://www.me-helloworlds.cn

2026-03-22 08:19:34

刚分手,心情不好!https://cn-kuailian.it.com

2026-03-22 20:16:07

楼主的帖子实在是写得太好了。文笔流畅,修辞得体!https://www.chrome-win.it.com

2026-03-23 07:09:36

看帖不回帖都是耍流氓!https://www.mac-helloworlds.cn

2026-03-24 01:45:48

以后就跟楼主混了!https://i-youdao.com.cn

2026-03-24 04:39:49

楼主的文笔不错!https://www-wps-cn.com

2026-03-25 00:38:22

今天是个特别的日子,值得纪念!https://im-sogou.com

2026-03-25 17:23:27

我对楼主的敬仰犹如滔滔江水绵延不绝!https://i-youdao.com.cn

2026-03-26 18:19:48

十分赞同楼主!https://i-youdao.com.cn

2026-03-27 02:39:07

楼主主机很热情啊!https://pc-helloworld.cn

2026-03-27 06:18:03

今天的心情很不错啊https://i-youdao.com.cn

2026-03-28 08:29:05

青春不在了,青春痘还在!https://a-wps.it.com

关闭广告
关闭广告