前言
咱们的网站或者程序,每一个页面和操作都需要请求后端接口来获取响应和渲染页面,抛开post
请求方式的接口不说,部分get
请求得到的数据,短时间内不会更新,或者短时间得到的响应数据不会变化,这个时候就可以把从接口得到的数据缓存下来,下次刷新或者是请求接口的时候,就不用请求接口,从而大幅度提高用户体验。
当然,如果服务器的流量很多且兆宽也比较大,可以自动忽略。
不过自研小网站,或者资讯类、文字类数据量比较大的程序就可以完全利用起来了。
实现
storage.ts
- 首先肯定是需要缓存的工具类,来直接使用
js
/**
* 封装操作localstorage本地存储的方法
*/
export const storage = {
//存储
set(key: string, value: any, expires: number) {
const obj = {
value: value,
expires: expires,//有效时间
startTime: new Date().getTime() // 记录存储数据的时间,转换为毫秒值存下来
}
// 判断是否设置了有效时间
if (obj.expires) {
// 如果设置了时间,把obj转换数据类型转换为字符串对象存起来
localStorage.setItem(key, JSON.stringify(obj))
}
else {
// 如果没有设置有效时间,直接把value值存进去
localStorage.setItem(key, JSON.stringify(obj.value))
}
},
//取出数据
get<T>(key: string) {
// 先定义一个变量临时存放提取的值
const temp = <T>JSON.parse(localStorage.getItem(key))
// 判断有没有设置expires属性
// 如果有,就需要判断是否到期了
if (temp && temp != "undefined" && temp != "null" && temp.expires ) {
let data = new Date().getTime()
if (data - temp.startTime > temp.expires) {
// 此时说明数据已过期,清除掉
localStorage.removeItem(key)
// 直接return
return
}
else {
// 如果没有过期就输出
return temp.value
}
}
else {
// 如果没有设置,直接输出
return temp
}
},
// 删除数据
remove(key: string) {
localStorage.removeItem(key)
}
};
/**
* 封装操作sessionStorage本地存储的方法
*/
export const sessionStorage = {
//存储
set(key: string, value: any) {
window.sessionStorage.setItem(key, JSON.stringify(value))
},
//取出数据
get<T>(key: string) {
const value = window.sessionStorage.getItem(key)
if (value && value != "undefined" && value != "null") {
return JSON.parse(value)
}
return null
},
// 删除数据
remove(key: string) {
window.sessionStorage.removeItem(key)
}
}
cacheAxios.ts
- 其实就是将自己的
axios
请求做个处理,请求的时候用封装的工具请求类即可 - 我举例的是
localStorage
,大家可以根据自行需要来使用sessionStorage
sessionStorage
就没有cacheTime
了,可以自行设置
js
import axios from '@/utils/axios'
import { storage } from '@/utils/storage'
interface optionsFace {
isCache?: boolean; // 是否缓存
cacheKey?: string; // 缓存key值
cacheTime?: number; // 缓存默认值 默认为3天 86400 * 3,单位秒
}
const request = async (config: any, {isCache = false, cacheKey, cacheTime = 86400 * 3}: optionsFace) => {
// 判断是否需要缓存数据,
if (isCache) {
const cacheData = storage.get(cacheKey)
if (cacheData) {
// 有缓存数据直接返回
return new Promise((resolve) => {
resolve(cacheData)
})
}else {
const resData = await axios(config)
// 根据自己的接口来判断
if (resData.code != 0) {
storage.set(cacheKey, resData, cacheTime * 1000)
}
// 返回结果
return new Promise((resolve) => {
resolve(resData)
})
}
} else {
return axios(config)
}
}
export default request
api.ts
- 接口工具类,使用方式就都一模一样的
js
// 使用封装的缓存axios
import request from '@/utils/cacheAxios';
/**
* 功能:获取 列表
*/
export const getList = (params: Object, options: Object) => {
return request({
url: '/Wikipedia/getList',
method: 'get',
params: params
}, options);
};
页面使用
js
/**
* 功能:获取 首页数据
*/
const getHome = () => {
// 这里的cacheKey,可以拼接上页码
// const cacheKey = 'homeData' + pageCurrent
// 配置里还有个时间参数,工具类里是默认3天,可以自行设置
getList({}, {isCache: true, cacheKey: 'homeData'}).then(res => {
// 逻辑处理、即使是缓存得到的数据也是一样的,不会影响业务处理
})
}
小结
- 很多人可能不会使用这个多余的操作,可是我自研了中小型网站,很多数据需要频繁渲染,且数据都是一样的,所以需要如此来降低服务器的成本和前端体验
- 缓存的数据,建议是列表类数据,全是明文的,这样即使别人拿到也没用
- 本文是基于
vue
,不过react
、小程序、uniapp
改一下同样适用