背景
- 现在有两个分属不同前端项目的页面:产品列表页与详情页。
- 需要支持手机浏览器访问这两个页面,并保持原进原出。
- 列表页跳转详情页,正常情况下使用
location.href进行跨项目跳转,但返回列表页会重新初始化,不能保持原进原出。
方案一
列表页跳转详情页前,将列表页当前状态保存到sessionStorage中。返回列表页时,不走初始化逻辑,直接从sessionStorage中恢复状态数据。
问题与难点
- 列表页十分复杂,涉及筛选、排序、tab、业务组件等等,页面上使用的组件很多,有些组件的状态是自己管理的,没有放到全局的store中;这就导致不能统一去往sessionStorage中存入数据。那些自己管理状态的组件(尤其是业务组件)还要自己在页面离开时往sessionStorage中写入数据。
- 不利于维护
方案二
只保留最终的列表页请求参数,包括tab、排序、筛选等,返回列表页时,使用这些状态重查列表。
问题与难点
- 无法完整的保持页面操作状态
- 用户翻到N页后,返回时要请求这N页数据。
方案三
使用iframe。列表页所在项目中提供一个路由页面专门使用iframe跳转到其它页面,只需给这个页面在$route.query中携带需要跳转页面的地址。
这样列表页可以使用keep-alive进行页面状态的缓存。
方案四
基于方案三进行改进,因为进入列表页后几乎都会进入到详情页,所以将iframe放到列表页,可以提前加载详情页资源。初始隐藏iframe,需要进入详情页面时,将iframe提到最顶层展示,这种方案连keep-alive都无需使用。
iframe调研
- iframe的创建好后,如果进行dom的移动,iframe会进行重载;所以如果要在最上层展示iframe,要么就在最上层创建iframe,要么就通过css去控制展示在上层。
- iframe的src发生变化,iframe也会重载。由于要提前加载详情页项目资源,会指定iframe的初始src;跳转到指定产品详情页时,不能再通过设置src来进入详情页。
- 设置
iframe.contentWindow.location.href也会导致iframe重载,仅设置iframe.contentWindow.location.search也不行。 - 在详情页中项目中使用
$router.push()或$router.replace()可以不重载iframe进入到对应的详情页 - 通过
iframe.contentWindow.history.replaceState()或pushState(),页面没有任何变化。 - 提前隐藏iframe,设置css
display:none不会导致iframe重载。