当前位置: 首页 > news >正文

青岛知名网站建设定制甘肃机械化建设工程有限公司网站

青岛知名网站建设定制,甘肃机械化建设工程有限公司网站,重庆市公路建设信息网官网,在线制作图片热区有这么一个需求#xff1a;列表页进入详情页后#xff0c;切换回列表页#xff0c;需要对列表页进行缓存#xff0c;如果从首页进入列表页#xff0c;就要重新加载列表页。 对于这个需求#xff0c;我的第一个想法就是使用keep-alive来缓存列表页#xff0c;列表和详情…有这么一个需求列表页进入详情页后切换回列表页需要对列表页进行缓存如果从首页进入列表页就要重新加载列表页。 对于这个需求我的第一个想法就是使用keep-alive来缓存列表页列表和详情页切换时列表页会被缓存从首页进入列表页时就重置列表页数据并重新获取新数据来达到列表页重新加载的效果。 但是这个方案有个很不好的地方就是如果列表页足够复杂有下拉刷新、下拉加载、有弹窗、有轮播等在清除缓存时就需要重置很多数据和状态而且还可能要手动去销毁和重新加载某些组件这样做既增加了复杂度也容易出bug。 接下来说说我的想到的新实现方案代码基于Vue3。 keep-alive 缓存和清除 keep-alive 缓存原理进入页面时页面组件渲染完成keep-alive 会缓存页面组件的实例离开页面后组件实例由于已经缓存就不会进行销毁当再次进入页面时就会将缓存的组件实例拿出来渲染因为组件实例保存着原来页面的数据和Dom的状态那么直接渲染组件实例就能得到原来的页面。 keep-alive 最大的难题就是缓存的清理如果能有简单的缓存清理方法那么keep-alive 组件用起来就很爽。 但是keep-alive 组件没有提供清除缓存的API那有没有其他清除缓存的办法呢答案是有的。我们先看看 keep-alive 组件的props include - string | RegExp | Array。只有名称匹配的组件会被缓存。 exclude - string | RegExp | Array。任何名称匹配的组件都不会被缓存。 max - number | string。最多可以缓存多少组件实例。 从include描述来看我发现include是可以用来清除缓存做法是将组件名称添加到include里组件会被缓存移除组件名称组件缓存会被清除。根据这个原理用hook简单封装一下代码 import { ref, nextTick } from vueconst caches  refstring[]([])export default function useRouteCache () {// 添加缓存的路由组件function addCache (componentName: string | string []) {if (Array.isArray(componentName)) {componentName.forEach(addCache)return}if (!componentName || caches.value.includes(componentName)) returncaches.value.push(componentName)}// 移除缓存的路由组件function removeCache (componentName: string) {const index  caches.value.indexOf(componentName)if (index  -1) {return caches.value.splice(index, 1)}}// 移除缓存的路由组件的实例async function removeCacheEntry (componentName: string) {    if (removeCache(componentName)) {await nextTick()addCache(componentName)}}return {caches,addCache,removeCache,removeCacheEntry} } hook的用法如下 router-view v-slot{ Component }keep-alive :includecachescomponent :isComponent //keep-alive /router-viewscript setup langts import useRouteCache from ./hooks/useRouteCache const { caches, addCache } useRouteCache()!-- 将列表页组件名称添加到需要缓存名单中 -- addCache([List]) /script 清除列表页缓存如下 import useRouteCache from /hooks/useRouteCacheconst { removeCacheEntry }  useRouteCache() removeCacheEntry(List) 此处removeCacheEntry方法清除的是列表组件的实例List 值仍然在 组件的include里下次重新进入列表页会重新加载列表组件并且之后会继续列表组件进行缓存。 列表页清除缓存的时机 进入列表页后清除缓存 在列表页路由组件的beforeRouteEnter勾子中判断是否是从其他页面Home进入的是则清除缓存不是则使用缓存。 defineOptions({name: List1,beforeRouteEnter (to: RouteRecordNormalized, from: RouteRecordNormalized) {if (from.name  Home) {const { removeCacheEntry }  useRouteCache()removeCacheEntry(List1)}} }) 这种缓存方式有个不太友好的地方当从首页进入列表页列表页和详情页来回切换列表页是缓存的但是在首页和列表页间用浏览器的前进后退来切换时我们更多的是希望列表页能保留缓存就像在多页面中浏览器前进后退会缓存原页面一样的效果。但实际上列表页重新刷新了这就需要使用另一种解决办法点击链接时清除缓存清除缓存。 点击链接跳转前清除缓存 在首页点击跳转列表页前在点击事件的时候去清除列表页缓存这样的话在首页和列表页用浏览器的前进后退来回切换列表页都是缓存状态只要当重新点击跳转链接的时候才重新加载列表页满足预期。 // 首页 Home.vuelirouter-link to/list clickremoveCacheBeforeEnter列表页/router-link /liscript setup langts import useRouteCache from /hooks/useRouteCachedefineOptions({name: Home })const { removeCacheEntry } useRouteCache()// 进入页面前先清除缓存实例 function removeCacheBeforeEnter () {removeCacheEntry(List) } /script 状态管理实现缓存 通过状态管理库存储页面的状态和数据也能实现页面缓存。此处状态管理使用的是pinia。 首先使用pinia创建列表页store import { defineStore } from piniainterface Item {id?: number,content?: string }const useListStore  defineStore(list, {// 推荐使用 完整类型推断的箭头函数state: ()  {return {isRefresh: true,pageSize: 30,currentPage: 1,list: [] as Item[],curRow: null as Item | null}},actions: {setList (data: Item []) {this.list  data},setCurRow (data: Item) {this.curRow  data},setIsRefresh (data: boolean) {this.isRefresh  data}} })export default useListStore 然后在列表页中使用store divel-page-header backgoBacktemplate #content状态管理实现列表页缓存/template/el-page-headerel-table v-loadingloading :datatableData border stylewidth: 100%; margin-top: 30px;el-table-column propid labelid /el-table-column propcontent label内容/el-table-column label操作template v-slot{ row }el-link typeprimary clickgotoDetail(row)进入详情/el-linkel-tag typesuccess v-ifrow.id listStore.curRow?.id刚点击/el-tag/template/el-table-column/el-tableel-paginationv-model:currentPagelistStore.currentPage:page-sizelistStore.pageSizelayouttotal, prev, pager, next:totallistStore.list.length/ /divscript setup langts import useListStore from /store/listStore const listStore useListStore()... /script 通过beforeRouteEnter钩子判断是否从首页进来是则通过 listStore.$reset() 来重置数据否则使用缓存的数据状态之后根据 listStore.isRefresh 标示判断是否重新获取列表数据。 defineOptions({beforeRouteEnter (to: RouteLocationNormalized, from: RouteLocationNormalized) {if (from.name  Home) {const listStore  useListStore()listStore.$reset()}} })onBeforeMount(()  {if (!listStore.useCache) {loading.value  truesetTimeout(()  {listStore.setList(getData())loading.value  false}, 1000)listStore.useCache  true} }) 缺点 通过状态管理去做缓存的话需要将状态数据都存在stroe里状态多起来的话会有点繁琐而且状态写在store里肯定没有写在列表组件里来的直观状态管理由于只做列表页数据的缓存对于一些非受控组件来说组件内部状态改变是缓存不了的这就导致页面渲染后跟原来有差别需要额外代码操作。 页面弹窗实现缓存 将详情页做成全屏弹窗那么从列表页进入详情页就只是简单地打开详情页弹窗将列表页覆盖从而达到列表页 “缓存”的效果而非真正的缓存。 这里还有一个问题打开详情页之后如果点后退会返回到首页实际上我们希望是返回列表页这就需要给详情弹窗加个历史记录如列表页地址为 /list打开详情页变为 /list?id1。 弹窗组件实现 // PopupPage.vuetemplatediv classpopup-page :class[!dialogVisible hidden]slot v-ifdialogVisible/slot/div /templatescript setup langts import { useLockscreen } from element-plus import { computed, defineProps, defineEmits } from vue import useHistoryPopup from ./useHistoryPopupconst props defineProps({modelValue: {type: Boolean,default: false},// 路由记录history: {type: Object},// 配置了history后初次渲染时如果有url上有history参数则自动打开弹窗auto: {type: Boolean,default: true},size: {type: String,default: 50%},full: {type: Boolean,default: false} }) const emit defineEmits([update:modelValue, autoOpen, autoClose] )const dialogVisible computedboolean({ // 控制弹窗显示get () {return props.modelValue},set (val) {emit(update:modelValue, val)} })useLockscreen(dialogVisible)useHistoryPopup({history: computed(() props.history),auto: props.auto,dialogVisible: dialogVisible,onAutoOpen: () emit(autoOpen),onAutoClose: () emit(autoClose) }) /scriptstyle langless .popup-page {position: fixed;left: 0;right: 0;top: 0;bottom: 0;z-index: 100;overflow: auto;padding: 10px;background: #fff;.hidden {display: none;} } /style 弹窗组件调用 popup-page v-modelvisible full:history{ id: id }Detail/Detail /popup-page 缺点 弹窗实现页面缓存局限比较大只能在列表页和详情页中才有效离开列表页之后缓存就会失效比较合适一些简单缓存的场景。 父子路由实现缓存 该方案原理其实就是页面弹窗列表页为父路由详情页为子路由从列表页跳转到详情页时显示详情页字路由且详情页全屏显示覆盖住列表页。 声明父子路由 {path: /list,name: list,component: ()  import(./views/List.vue),children: [{path: /detail,name: detail,component: ()  import(./views/Detail.vue),}] } 列表页代码 // 列表页 templateel-table v-loadingloading :datatableData border stylewidth: 100%; margin-top: 30px;el-table-column propid labelid /el-table-column propcontent label内容/el-table-column label操作template v-slot{ row }el-link typeprimary clickgotoDetail(row)进入详情/el-linkel-tag typesuccess v-ifrow.id  curRow?.id刚点击/el-tag/template/el-table-column/el-tableel-paginationv-model:currentPagecurrentPage:page-sizepageSizelayouttotal, prev, pager, next:totallist.length/!-- 详情页 --router-view classpopyp-page/router-view /templatestyle langless scoped .popyp-page {position: fixed;top: 0;bottom: 0;left: 0;right: 0;z-index: 100;background: #fff;overflow: auto; } /style
http://www.hkea.cn/news/14363392/

相关文章:

  • 怎么样免费做公司网站专业网站建设品牌策
  • 网站建设的来源网站建设交接表
  • dede购物网站搬搬屋源码网
  • 网站系统php源码慈溪做无痛同济 amp 网站
  • 上海专业网站建设机构保险网站建设的目标
  • 福永做网站的公司做拍卖网站怎么样
  • 做企业网站的多少钱百度推广运营这个工作好做吗
  • 做网站PV分类目录网站怎么做
  • 宁波seo网站推广上网导航下载
  • 免费做漫画网站方正隶变简体可以做网站用么
  • wamp个人网站开发来源阜南县建设局网站
  • 摄影网站制作软件电子商务网站建设流程
  • 泰安网页建设旺道seo网站优化大师
  • 博物馆网站建设的根本意义国外ps设计图网站
  • 滨州网站设计网站备案容易通过吗
  • 网站开发php是什么意思渠道推广费用咨询
  • 宁波怎么建网站模板电子商务营销网站建设
  • wordpress绕过媒体seo公司中国
  • 医疗设计网站百度公司网站排名怎么做
  • google建立网站aso推广
  • 制作一个企业网站过程综合电商网站建设需求文档
  • 用vs2010做免费网站模板下载地址往网站添加图片吗
  • 分享到各大网站 代码专门做任务的网站6
  • 西安蓝海网站建设建设银行官方网站客户端
  • 学院网站改造方案一天挣5000元的偏门路子
  • 软件定制网站建设国外网站后台模板下载
  • 徐州网站建设 徐州网站推广做网站自己有模板要花多少钱
  • 浏览器网站入口网站功能介绍是什么
  • 自己网站视频直播怎么做优化网站用什么软件好
  • 分析seo网站怎么给一个网站做搜索功能