范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

前端在Vue3这样子写页面更快更高效

  前言
  在开发管理后台过程中,一定会遇到不少了增删改查页面,而这些页面的逻辑大多都是相同的,如获取列表数据,分页,筛选功能这些基本功能。而不同的是呈现出来的数据项。还有一些操作按钮。
  对于刚开始只有 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(   listRequestFn: Function ) {   // 忽略其他代码   const list = ref([]); }
  在useList中创建一个loadData函数,用于调用获取数据函数,该函数接收一个参数用于获取指定页数的数据(可选,默认为curPage的值)。执行流程设置加载状态调用外部传入的函数,将获取到的数据赋值到list和total中关闭加载态
  这里使用了 async/await 语法,假设请求出错、解构出错情况会走 catch 代码块,再关闭加载态
  这里需要注意,传入的 listRequestFn 函数接收的参数数量和类型是否正常对应上 请根据实际情况进行调整export default function useList(   listRequestFn: Function ) {   // 忽略其他代码   // 数据   const list = ref([]);   // 过滤数据   // 获取列表数据   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 函数监听数据,当curPage,pageSize的值发生改变时调用loadData函数获取新的数据。export default function useList(   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) {   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) {   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,   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,   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,   exportRequestFn?: Function,   options = DEFAULT_OPTIONS ) {   // ... }
  在没有传递钩子的情况霞,推荐设置默认的失败时信息显示优化loadData,exportFile函数
  基于 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 使用方法
  本文useList的完整代码在 github.com/QC2168/snip…
  如果您对该hook有更好的建议,欢迎pr或者在评论区留言哦
  另外,为了在日常开发中节省找封装代码片段的时间和提高工作效率(摸 时间++),该仓库还存放一些第三方封装的代码片段 ✨,方便大家拿取 (持续更新中 ~ ~ )
  文章来源:_island_https://juejin.cn/post/7172889961446768670
人气动漫狐妖小红娘改编剧来了,有望刷新古偶剧的颜值巅峰!国产动漫的强势崛起,也加快了影视行业的蓬勃发展!我发现近些年,小说动漫电视剧,三者之间形成了一条完整的产业链,各类题材的影视化改编层出不穷,中式美感也成为了现今最火爆的一大元素。在演员拍戏有多拼?朱一龙无替身连滚17次,刘亦菲冬季泡水10个小时文2号探秘人编辑2号探秘人大家都觉得演员光彩照人,拍戏就背背台词,动动嘴皮,摔摔东西发发脾气就可以了。那就想得太简单了,其实他们所拍的每一部剧,可能几分钟的镜头,要反复拍好多次,付范伟和林志玲演夫妻,大家都以为是我赚了,其实我特别委屈2015年,范伟拿到了道士下山的剧本,看完后,他问陈凯歌,跟他演夫妻的女演员是谁。陈凯歌回答台湾第一美女林志玲,怎么样,不错吧?谁知范伟一听,马上摇头不行不行,这我不能演,我跟她演充满诡异的乌鸦乌鸦是30年前的老片了,因为李小龙之子李国豪拍摄时意外身亡使此片笼罩着一股神秘感,这一天是4月1日。当一个人死后,乌鸦会将他的灵魂带回他的栖息地,倘若这个人的灵魂得不到平静,则被迫历史人物故事你知道皇帝也会随意甩锅吗?上官仪惨遭灭门祸唐高宗李治怒火中烧,对匆匆赶来的宰相上官仪下令快给朕拟旨,我要把这个伤天害理无法无天的女人废掉!废掉!废掉!就这一句话,就给不明所以的上官仪带来了灭门之灾!高宗李治为何如此愤怒?只原解放军20军60师驻防金华的历史往事(下篇2)历史笔记向60师大院子女致以衷心的祝福!前情概要笔者已经撰写了原20军60师驻防金华的历史往事上篇中篇下篇1共三篇。本期将发布原20军60师驻防金华的历史往事(下篇2)。在此,首先到狂飙中的京海市走一遭,能看到什么?开年最火的剧非狂飙莫属尽管已播出大结局但狂飙的名字依旧每天霸占着热搜榜其主要拍摄地广东江门也被更多人所熟知狂飙在豆瓣上的评分广东省江门市是粤港澳大湾区的重要节点城市历史悠久,文化底狂飙中毒贩扮演者现实中竟然真涉毒?剧组发声近日,有网友指出,狂飙里毒贩钟阿四的扮演者,在现实生活中可能真的是涉毒人员。扮演者原名为含笑,曾是一名歌手,2009年吸毒被抓。后来改名为韩朴俊,如今出现在狂飙中。2月11日晚,狂不明飞行物也狂飙最近,多个国家出现了不明飞行物,引发了全球的关注。这些不明飞行物到底是什么?有人认为它们可能是外星人,但也有人认为它们可能是地球上的某种新型飞行器。最近狂飙火得一塌糊涂,想不到UF陈飞宇正面回应!不愧爹妈都是大佬,这段声明有水平从合照被曝出,到陈飞宇方正面回应,时间已经过去了近一天。而在这短短的一天时间,爆炸式的信息被扒了出来。先是女方的背景,随后又是女方已婚的事实,一时间网上各种邻居同学都出来爆料了,简女生应聘,私人助理潜规则会有补贴,公司财务要求会煮饭把地球的故事讲给宇宙广东珠海,一位网友在网上应聘电商运营一职位。因为她有过相关工作经验,无论是学历还是工作职责都符合要求,所以投了简历。结果,在和招聘者沟通的过程中,被问道你这边有
姥爷我想你常嬉皮笑脸地和众人说小盒子才是你永远的家如今,那个吃他饭长大的老赵永远地长眠在了小盒子里你已卧床5年看着你时而清醒时而糊涂,饱受疼痛折磨曾不孝地想,也许尘归尘,土归土是对你最好的解这座低调了2500年的江南古城,鲜到醉人,到了最好吃的时候了与北方萧瑟的秋天相比,记忆里江南的秋总是一晃而过,轻描淡写。过了十一月,我却在深秋最温柔悠然的浙江绍兴,看见了别样的江南。一场飘摇的雨洋洋洒洒后,银杏黄了,桂花飘香,梧桐叶落,火红拼多多业绩爆炸式增长却尤为低调,究竟是自谦还是底气不足?过去,人们对拼多多的印象是烧钱换用户,未来是否具备持续盈利能力,始终是对拼多多的一大隐忧。不过,从最近两年的表现看,拼多多变了。最新公布的拼多多第三季度财报显示,拼多多三季度总营收这座低调了2500年的江南古城,鲜到醉人,到了最好吃的时候了头条创作挑战赛与北方萧瑟的秋天相比,记忆里江南的秋总是一晃而过,轻描淡写。过了十一月,我却在深秋最温柔悠然的浙江绍兴,看见了别样的江南。一场飘摇的雨洋洋洒洒后,银杏黄了,桂花飘香,卡其裤平底鞋才是真舒适高级,跟大衣简直绝配,三木都爱了轻盈感和厚重感,一直都是冬季穿搭的气质重头戏。在层层叠叠的厚重穿搭当中,想要劈开一道清爽而又得体的造型设计,每一位穿着者都有自己独到的审美之处。毫不例外的是,单品选择的正确与否,直司马懿立遗嘱子孙不准为我扫墓,1769年过去,才发现其高明之处东汉末年社会动荡,群雄割据烽火连天,在经历了几年混战之后,逐渐形成了三国鼎立之势,曹操一统了北方刘备占据益州,而孙权则雄踞于江东。然而最后一统三国的并不是这三个国家的其中之一,取而大厂数据分析师进阶之路,一个合格的数据分析师如何造数?不会造数的数据分析师,不是一个好数据分析师,这里所说的造数,并不是让我们数据分析师去胡编乱造数据,而是在日常数据分析过程中我们需要模拟生成一些数据用于测试,也就是测试数据。本文所使加强和完善现代金融监管(认真学习宣传贯彻党的二十大精神)加强和完善现代金融监管郭树清党的二十大报告提出,加强和完善现代金融监管,强化金融稳定保障体系,依法将各类金融活动全部纳入监管,守住不发生系统性风险底线。必须按照党中央决策部署,深化美丽的青藏高原,隐藏了多少战略级矿藏?西藏变资源福地中国是一个地大物博的国家,物产资源丰富,文化历史悠久,九百六十万平方公里的土地上拥有着五十六个民族,版图辽阔跨越疆域广泛,所以气候上地势上都有很大的差异性,这也造就了中国从北到南,早安云南云上梯田撒马坝,雕刻在大地上的诗行有人说,不到撒玛坝,不知梯田大。红河县撒玛坝梯田以面积宽广气势恢宏著称,是世界上集中连片最大的梯田,也是全国唯一在一个视角点就能将万亩梯田尽收眼底的观赏区。鸟瞰撒玛坝组照撒马坝梯田菏泽鲁西新区八一路小学开展二年级分批入少先队活动中国山东网感知山东10月13日讯(记者孙慧敏通讯员王艳)为庆祝中国少年先锋队建队73周年,帮助新队员树立规范意识,增强少先队员的光荣感和组织归属感,菏泽鲁西新区八一路小学开展了二年