# API缓存

前面已经多组件、页面做了缓存。但是在某些情况下,如果api查询比较耗时,但是数据的时效性有比较低的情况下,我们可以对这个部分api接口进行数据缓存,从而提高页面的响应速度。

# 安装需要的npm包

npm i @nuxtjs/axios --save

npm i axios-extensions --save

npm i lru-cache --save

# 配置 axios

/plugins/axios.js 文件中做如下配置

import { cacheAdapterEnhancer } from 'axios-extensions'
import LRUCache from 'lru-cache'
const BASE_API_URL = '/'

// api数据缓存存储对象
const cacheCfg = new LRUCache({
  // 有效期60s
  maxAge: 1000 * 60,
  // 最大缓存数量
  max: 1000,
})

export default function ({ app: { $axios } }) {
  // $axios.defaults.baseURL = process.env.NUXT_ENV_BASE_URL
  const baseURL = BASE_API_URL

  $axios.defaults.baseURL = baseURL
  $axios.interceptors.request.use((config) => {
    return config
  })
  // 拦截 400 500
  $axios.interceptors.response.use((response) => {
    if (/^[4|5]/.test(response.status)) {
      return Promise.reject(response.statusText)
    }
    return response.data
  })

  // 配置适配器,如果 options 中带有 useCache 字段,并且值为 true,则该请求会被缓存
  const defaultAdapter = $axios.defaults.adapter
  $axios.defaults.adapter = cacheAdapterEnhancer(defaultAdapter, {
    enabledByDefault: false,
    cacheFlag: 'useCache',
    defaultCache: cacheCfg,
  })

  $axios.interceptors.response.use(
    (response) => {
      if (/^[4|5]/.test(response.status)) {
        return Promise.reject(response.statusText)
      }
      return response
    },
    (error) => {
      // 服务端日志打印
      // @ts-ignore
      if (process.server) {
        if (error.response && error.response.config) {
          const config = error.response.config
          console.log(
            `【请求出错】: [${config.method}]${config.baseURL}${
              config.url
            }: [params]${JSON.stringify(
              config.params || {}
            )}: [data]${JSON.stringify(config.data || {})}`
          )
        } else {
          console.log(`【请求出错】: ${error.toString()}`)
        }
      }
      return Promise.reject(error)
    }
  )
}

# 使用

pages/apiCache.vue 文件中使用如下方法调用

<template>
  <div class="container">
    <div>
      <h1 class="title">
        nuxt-practice
      </h1>
      <div class="links">
        <nuxt-link to="/index2">
          index2
        </nuxt-link>
        <br />
        <nuxt-link to="/pageCache">
          pageCache
        </nuxt-link>
        <br />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ApiCache',
  async asyncData({ $axios }) {
    try {
      const res = await $axios.get('/apiCacheData', {
        // 使用api缓存
        useCache: true,
      })
      return {
        list: res.data,
      }
    } catch (e) {
      console.log(e)
    }
  },
  data() {
    return {
      list: [],
    }
  },
  mounted() {
    console.log(this.list)
  },
}
</script>

在服务器端在缓存有效期内的,对统一请求只会发起一次数据请求,其余的请求都将直接返回缓存数据。 在浏览器端,一次回话周期内(页面没有被刷新的情况下),在缓存有效期内只会发起一次真实数据请求,其余的请求将直接返回缓存数据。