网站建设模块需求分析,怎样搭建电商平台,徐州建设网站价格,网页设计模板网这里给大家分享我在网上总结出来的一些知识#xff0c;希望对大家有所帮助 前言 在开发管理后台过程中#xff0c;一定会遇到不少了增删改查页面#xff0c;而这些页面的逻辑大多都是相同的#xff0c;如获取列表数据#xff0c;分页#xff0c;筛选功能这些基本功能。而… 这里给大家分享我在网上总结出来的一些知识希望对大家有所帮助 前言 在开发管理后台过程中一定会遇到不少了增删改查页面而这些页面的逻辑大多都是相同的如获取列表数据分页筛选功能这些基本功能。而不同的是呈现出来的数据项。还有一些操作按钮。 对于刚开始只有 12 个页面的时候大多数开发者可能会直接将之前的页面代码再拷贝多一份出来而随着项目的推进类似页面数量可能会越来越多这直接导致项目代码耦合度越来越高。 这也是为什么在项目中一些可复用的函数或组件要抽离出来的主要原因之一 下面我们封装一个通用的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 useListItemType extends Object(listRequestFn: Function
) {// 忽略其他代码const list refItemType[]([]);
}在useList中创建一个loadData函数用于调用获取数据函数该函数接收一个参数用于获取指定页数的数据(可选默认为curPage的值)。 执行流程 设置加载状态调用外部传入的函数将获取到的数据赋值到list和total中关闭加载态 这里使用了 async/await 语法假设请求出错、解构出错情况会走 catch 代码块再关闭加载态 这里需要注意传入的 listRequestFn 函数接收的参数数量和类型是否正常对应上 请根据实际情况进行调整 export default function useListItemType extends Object(listRequestFn: Function
) {// 忽略其他代码// 数据const list refItemType[]([]);// 过滤数据// 获取列表数据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 useListItemType extends Object(listRequestFn: Function
) {// 忽略其他代码// 监听分页数据改变watch([curPage, pageSize], () {loadData(curPage.value);});
}现在实现了基本的列表数据获取 实现数据筛选器 在庞大的数据列表中数据筛选是必不可少的功能 通常我会将筛选条件字段定义在一个ref中在请求时将ref丢到请求函数即可。 在 useList 函数中第二个参数接收一个filterOption对象对应列表中的筛选条件字段。 调整一下loadData函数在请求函数中传入filterOption对象即可 注意传入的 listRequestFn 函数接收的参数数量和类型是否正常对应上 请根据实际情况进行调整 export default function useListItemType extends Object,FilterOption extends Object
(listRequestFn: Function, filterOption: RefObject) {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 useListItemType extends Object,FilterOption extends Object
(listRequestFn: Function, filterOption: RefObject) {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();};
}导出功能 除了对数据的查看有些界面还需要有导出数据功能(例如导出 csvexcel 文件)我们也把导出功能写到useList里 通常导出功能是调用后端提供的导出Api获取一个文件下载地址和loadData函数类似从外部获取exportRequestFn函数来调用Api 在函数中新增一个exportFile函数调用它。 export default function useListItemType extends Object,FilterOption extends Object
(listRequestFn: Function,filterOption: RefObject,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 useListItemType extends Object,FilterOption extends Object
(listRequestFn: Function,filterOption: RefObject,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 useListItemType extends Object,FilterOption extends Object
(listRequestFn: Function,filterOption: RefObject,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 函数 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;// 执行成功钩子options?.message?.GET_DATA_IF_SUCCEED message(options.message.GET_DATA_IF_SUCCEED);options?.requestSuccess?.();} catch (error) {options?.message?.GET_DATA_IF_FAILED errorMessage(options.message.GET_DATA_IF_FAILED);// 执行失败钩子options?.requestError?.();} finally {loading.value false;}
};exportFile 函数 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);// 显示信息options?.message?.EXPORT_DATA_IF_SUCCEED message(options.message.EXPORT_DATA_IF_SUCCEED);// 执行成功钩子options?.exportSuccess?.();} catch (error) {// 显示信息options?.message?.EXPORT_DATA_IF_FAILED errorMessage(options.message.EXPORT_DATA_IF_FAILED);// 执行失败钩子options?.exportError?.();}
};useList 使用方法 templateel-collapse classmb-6el-collapse-item title筛选条件 name1el-form label-positionleft label-width90px :modelfilterOptionel-row :gutter20el-col :xs24 :sm12 :md8 :lg8 :xl8el-form-item label用户名el-inputv-modelfilterOption.nameplaceholder筛选指定签名名称//el-form-item/el-colel-col :xs24 :sm12 :md8 :lg8 :xl8el-form-item label注册时间el-date-pickerv-modelfilterOption.timeRangetypedaterangeunlink-panelsrange-separator到start-placeholder开始时间end-placeholder结束时间formatYYYY-MM-DD HH:mmvalue-formatYYYY-MM-DD HH:mm//el-form-item/el-colel-col :xs24 :sm24 :md24 :lg24 :xl24el-row classflex mt-4el-button typeprimary clickfilter筛选/el-buttonel-button typeprimary clickreset重置/el-button/el-row/el-col/el-row/el-form/el-collapse-item/el-collapseel-table v-loadingloading :datalist border stylewidth: 100%el-table-column label用户名 min-width110pxtemplate #defaultscope{{ scope.row.name }}/template/el-table-columnel-table-column label手机号码 min-width130pxtemplate #defaultscope{{ scope.row.mobile || 未绑定手机号码 }}/template/el-table-columnel-table-column label邮箱地址 min-width130pxtemplate #defaultscope{{ scope.row.email || 未绑定邮箱地址 }}/template/el-table-columnel-table-column propcreateAt label注册时间 min-width220px /el-table-column width200px fixedright label操作template #defaultscopeel-button typeprimary link clickdetail(scope.row)详情/el-button/template/el-table-column/el-tablediv v-iftotal 0 classflex justify-end mt-4el-paginationv-model:current-pagecurPagev-model:page-sizepageSizebackgroundlayoutsizes, prev, pager, next:totaltotal:page-sizes[10, 30, 50]//div
/template
script setup langts
import { UserInfoApi } from /network/api/User;
import useList from /lib/hooks/useList/index;
const filterOption refUserInfoApi.FilterOptionType({});
const {list,loading,reset,filter,curPage,pageSize,reload,total,loadData,
} useListUserInfoApi.UserInfo[], UserInfoApi.FilterOptionType(UserInfoApi.list,filterOption
);
/script本文useList的完整代码在 github.com/QC2168/snip… 本文转载于: https://juejin.cn/post/7172889961446768670 如果对您有所帮助欢迎您点个关注我会定时更新技术文档大家一起讨论学习一起进步。