背景
最近在对公司node+jquery
捞系统基层进行版本升级,使用最新技术栈vue + ts + vite + pinia
,对于捞系统原有页面将会进行iframe
不会再其基础上进行修改,大大减少了维护成本,但是由于其页面较多,且页面之间存在关联,所以需要对页面进行缓存,避免重复加载,提升用户体验,其中也遇到了一系列兼容问题,总结如下:
对于系统升级,当然要使用最新技术栈了,这样公司使用的技术栈就会统一,也不会因为技术栈不统一导致个人成长缓慢;对于相对系列问题也可以进行小组探讨;
从计划开始部署到真正上手改造花费将近一周时间,底层框架结构采用vue
,里层内容采用iframe
链接老项目页面;
Start
开始进行对系统技术的升级,大致升级的范围:
- 登录,重置密码重构,摒弃原来
jquery
页面
- 路由,权限的重置,需要后端开发人员配合,现在市面上的中后台系统的路由和权限基本都是后端来管理,很少使用前端路由
- 基础库,方法的编写,对于常用的方法,
hooks
需要统一封装管理
- 常用枚举的封装,接口定义,类型定义
- 请求拦截,相应的封装;
环境的配置
当然对于企业项目,多环境已经是常见的,开发环境,测试环境,预发布环境,线上环境等等;对于这些环境一些请求的域名,配置参数当然也是不一样的,这时候就可以在.env
文件中配置,大概配置项如下:
1 2 3 4 5 6
| VITE_APP_API_URL='http://www.wangxiaoze.wang' VITE_APP_API_KEY='abc' VITE_APP_APP_ID='123456'
VITE_APP_IFRAME_HOST='http://www.wangxiaoze.wang'
|
utils, hooks 等基础配置的封装
utils
基础的方法,正则的封装等等;
hooks
的封装,对于一些常用的方法,比如loading
,message
,dialog
,confirm
, loading
等方法,需要统一封装管理;
config
对一些系统级的配置项,如:七牛的配置,标题,logo 的配置等等
store-pinia
的配置
axios
的封装,对于请求的拦截,响应的封装,请求的封装等等
api
的封装,对于一些接口的封装,如:七牛的图片上传,七牛的图片删除,七牛的图片列表等等
axios, api 的封装
对于axios
的使用,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| const instance: AxiosInstance = axios.create({ baseURL: `${import.meta.env.VITE_APP_BASE_URL}`, timeout: 60000, });
instance.interceptors.request.use( (config: InternalAxiosRequestConfig) => { return config; }, error => error );
instance.interceptors.response.use( (response: AxiosResponse) => { return response.data; }, error => { return Promise.reject(error.response); } );
interface IHttpResult<T> { code: number; message: string; data: T; success: boolean; }
const httpServer = { get<T = any, U = any>(url: string, params: U): Promise<IHttpResult<T>> { return instance.request(getParamsConfig(url, "get", params)); }, post<T = any, U = any>(url: string, params: U): Promise<IHttpResult<T>> { return instance.request(getParamsConfig(url, "post", params)); }, put<T = any, U = any>(url: string, params: U): Promise<IHttpResult<T>> { return instance.request(getParamsConfig(url, "put", params)); }, delete<T = any, U = any>(url: string, params: U): Promise<IHttpResult<T>> { return instance.request(getParamsConfig(url, "delete", params)); }, postForQuery<T = any, U = any>( url: string, params: U ): Promise<IHttpResult<T>> { return instance.request( getParamsConfig( url, "post", qs.stringify(params, { arrayFormat: "repeat", }) ) ); }, };
export { instance as axios, httpServer };
|
系统采用的是ts
,那么对于api
的管理使用枚举整理,相关api
的配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| enum UsetApi { UploadImage = "/api/upload/image", DeleteImage = "/api/upload/delete", ImageList = "/api/upload/list", }
import { httpServer } from "@/http";
export function getList<T, U>(data: U) { return httpServer.get<T>(UsetApi.ImageList, data); }
|
iframe 内嵌页面缓存
刚开始使用iframe
会发现一个问题,就是iframe
内嵌页面刷新后,iframe
会重新加载,导致页面会重新刷新,iframe 资源也会重新加载,会造成性能影响 那么如何解决呢?
- 使用
v-show
这样就可以避免刷新资源的问题
- 定位将 iframe 页面定位可视区域之外;
1 2 3 4 5
| <iframe v-for="item in routes" :key="item.path" v-show="item.path === route.path" />
|
虽然发现不会再次请求资源,刷新页面,但是会发现一个细节问题,那就是滚动条不会定位到上次的位置,这样用户频繁跳转页面,滚动条不会定位,会造成一定的使用不便;
另外的一中方案可以解决此类问题;
老系统的预览图片,打开标签页兼容
捞系统的预览图片会打开新的标签页,但是新系统要使用element-plus
的预览图片的样式,当然打开标签页也是同样问题;
想要同时解决新老系统的兼容问题,那么可以参考一下方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| window.parent.postMessage( { command: "open", data: { url: url, }, }, "*" );
window.addEventListener("message", function (e) { if (e.data.command === "open") { } });
window.removeEventListener("message", function (e) { if (e.data.command === "open") { } });
|
当然图片或者其他也是类似操作;