使用场景
防止用户过渡刷新或切换界面,不断的请求后端接口,所以在前端对用户拿到的部分数据进行缓存。
特别是查看分页数据的情况,用户频繁切换界面是可以有效的对数据进行缓存。
目录结构
WebSql.js 创建数据库表,储存key,value,过期时间
import Vue from 'vue'
import {executeSql} from '@/utils/localDb'
const WebSql=function(){
if(window.openDatabase){
var db = openDatabase('xb','1.0','xiaobao',200*1024*1024);
Vue.prototype.$db=db;
if(!db){
console.log("本地数据库创建失败");
}else{
executeSql('CREATE TABLE IF NOT EXISTS local_cache (key,value,time)');
console.log('本地数据库创建成功');
}
}else{
console.log('不支持本地存储');
}
};
export default WebSql;
localDb.js
import Vue from 'vue'
export function executeSql (sqlStatement, arg, callback, errorCallback) {
Vue.prototype.$db.transaction(function (tx) {
tx.executeSql(sqlStatement, arg, callback, errorCallback);
});
}
export function insert (key,value,time) {
value=JSON.stringify(value);
executeSql('INSERT INTO local_cache (key,value,time) VALUES (?,?,?)',[key,value,time])
}
export function deletebykey(key) {
executeSql('delete from local_cache where key = ?',[key])
}
export function deletebytime() {
executeSql('delete from local_cache where time > 0 and time < '+gettime())
}
//设置值的值和过期时间
export function setcache (key,value,time) {
if(time!==0){
deletebykey(key);
insert(key,value,time>0?1000*time+gettime():-1)
}
deletebytime();
}
//获取key的值
export function getcache (key,value) {
deletebytime();
var returnstr;
Vue.prototype.$db.transaction( function (tx) {
tx.executeSql('SELECT * FROM local_cache where key = ?', [key], function (tx, results) {
var len = results.rows.length, i;
if (len && len > 0) {
returnstr=JSON.parse(results.rows.item(0).value);
}
value(returnstr);
}, a=>{
value(returnstr)
});
});
}
//刷新key的有效期
export function expire (key,time) {
executeSql('update local_cache set time = ? where key = ? ',[1000*time+gettime(),key])
}
export function gettime () {
return new Date().getTime();
}
main.js新增
import WebSql from '@/utils/WebSql' Vue.use(WebSql)
========================================上面的代码可以基本实现缓存====================================
request.js
请求工具类,这个工具是来源于ruoyi-vue,大家需要根据自己的项目再修改一下。
import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?';
for (const propName of Object.keys(config.params)) {
const value = config.params[propName];
var part = encodeURIComponent(propName) + "=";
if (value && typeof(value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
url += subPart + encodeURIComponent(value[key]) + "&";
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
if (code === 401) {
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
/* store.dispatch('LogOut').then(() => {
location.href = '/index';
})*/
})
} else if (code === 500) {
Message({
message: msg,
type: 'error'
})
return Promise.reject(new Error(msg))
} else if (code !== 200) {
Notification.error({
title: msg
})
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
带有缓存的request工具类
cacheRequest.js
import request from '@/utils/request'
import {getcache, setcache} from '@/utils/localDb'
export function cacheRequest (url,method,data,time) {
if(time!==0){
var key=JSON.stringify({url:url,method:method,data:data});
return new Promise(function(resolve, reject) {
getcache(key,(value)=>{
console.log(value)
if(value){
resolve(value)
}else{
request({
url: url,
method: method,
data: data
}).then(a=>{
setcache(key,a,time);
resolve(a)
})
}
})
});
}else{
return request({
url: url,
method: method,
data: data
})
}
}
==============到这里就可以了=================
后面这些是大家如果可以用上的话,也可以拷贝到自己项目,来源于ruoyi-vue
errorCode.js
export default {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'404': '访问资源不存在',
'default': '系统未知错误,请反馈给管理员'
}
auth.js
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
===============以下是我用于测试界面,拷贝到自己项目后添加到自己路由里即可================
项目需要引入element-ui,或者自己修改一下。
<template>
<div>
<div>
{{returnstr}}
</div>
<el-input v-model="key">key</el-input>
<el-input v-model="value">value</el-input>
<el-input v-model="time">time</el-input>
<el-input v-model="method">method</el-input>
<el-button @click="add()">
新增
</el-button>
<el-button @click="get()">
查询
</el-button>
<el-button @click="ajaxtest()">
ajax
</el-button>
</div>
</template>
<script>
import {getcache, setcache} from '@/utils/localDb'
import {cacheRequest} from '@/utils/cacheRequest'
export default {
name: 'test.vue',
data( ) {
return{
key:'http://localhost/dev-api/captchaImage',//你的后端接口 或者存缓存的key
value:'1234',//接口参数或者存缓存的value
time:10,//缓存过期时间 为0则不缓存,小于0则不过期。
returnstr:'这里是显示返回的结果',
method:'GET',
}
},
methods:{
add(){
setcache(this.key,this.value,this.time)
},
get(){
this.returnstr=getcache(this.key, (value)=> {
this.returnstr=value;
});
},
ajaxtest(){
cacheRequest(this.key,this.method,this.value,this.time)
.then(a=>{
this.returnstr=a;
})
}
}
}
</script>
<style scoped>
</style>
写的相对不是那么的规范,仅供大家参考。