likes
comments
collection
share

六、本地缓存处理

作者站长头像
站长
· 阅读数 59

前言

通常情况前端会对于一些常用而不经常变化的信息做一些缓存,比如 tokenuserInfo等。而据我了解,前端目前的缓存分为两种方式,

  • 本地缓存: 存在浏览器端,例如:cookieLocalStorageSessionStorage等。
  • 全局状态管理: 存在内存中,例如:vuexpinia

其实选择哪一种都可以,任何方案都有自己的优点和缺点,这里我使用的本地缓存为LocalStorage,简单易用,缺点就是安全性相比于cookie差了点,状态管理使用 pinia,更加契合 VUE3 组合式 APITS 类型支持。想进一步了解,参考官网:pinia.vuejs.org/

1. 整合 pinia

如果是使用官方脚手架搭建的工程,选择了 pinia 将会自动帮我们整合好,没有选择也没关系,因为官方都是最简单的引入,实际使用还是要做一些调整的。对于我来说选择唯一的好处就是不用再 npm install 一下了。

npm install pinia

2. 按模块化定义 store

整合好了之后这里要定义 store, 我理解的 store 就是一个全局的数据仓库,用来存放全局状态的数据,为了便于管理,这里我将按模块进行 store 的定义

六、本地缓存处理

将默认生成的 stores 进行修改,创建对应的文件夹和文件

  • constant: index.ts 用来存放定义的一些全局常量信息,暂时不是很多,所以统一放在了一个文件下。
  • modules: 按模块定义对应的 store, user.ts 表示用户相关数据存储的仓库
  • index.ts: 导出所有模块

在引入 pinia 的时候做一些调整,不直接在 main.ts 里引入,这样做的好处在于,之后对于 pinia 集成一些插件,或者做一些其他配置,可以独立出来,不用全部堆积在 main.ts

这样定义 store

// user.ts
import { defineStore } from 'pinia'

// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useUserInfoStore = defineStore('userInfo', {
  // 其他配置...
})

导出

import { createPinia } from 'pinia'

const store = createPinia()

export default store

main.ts 中引入

//main.ts
...
// 引入 pinia
import store from './stores'

const app = createApp(App)
app.use(store)
...

3. 使用

在了 storeactions 里去处理请求,获取到数据后放入缓存中就可以了。

主要流程代码

// LoginPage.vue
// 获取用户信息缓存仓库
const userInfo = useUserInfoStore()

// 处理登录方法
const handleLogin = async () => {
  // 表单验证
  const valid = await ruleFormRef.value?.validate()
  // 校验不成功直接 return
  if (!valid) {
    return false
  }
  // 校验成功进行后续操作
  // 1.加载 loading
  loading.value = true
  // 2.登录请求 获取token
  userInfo
    .login(loginData)
    .then(() => {
      // 跳转
      router.push('/')
    })
    .catch(() => {
      // 验证失败,做一些其他工作
    })
    .finally(() => {
      // 验证结束,隐藏loading
      loading.value = false
    })
}

userStore处理

import { defineStore } from 'pinia'
import type { LoginData, UserInfo } from '@/types/user'
import { setItem } from '@/utils/storage'
import { TOKEN } from '../constant'
import { login, getUserInfo } from '@/api/user'
export const useUserInfoStore = defineStore('userInfo', {
  state: () => {
    // 用户信息
    return {
      user: {} as UserInfo
    }
  },
  actions: {
    // 登录获取token
    async login(loginForm: LoginData) {
      const token = await login(loginForm)
    },

    // 获取用户信息
    async getUserInfo() {
      this.user = await getUserInfo()
    }
  }
})

至此 pinia 可以正常拿到 token 了。但是不是最终想要的结果,正常逻辑应该是,请求获取 token ,将 token 放入本地缓存,再携带 token 获取用户信息,之后将用户信息缓存到 pinia 中。接下来完成 localStorage 部分的编码

4. 编写 localStorage 工具类

这里就不赘述了,看代码

// storage.ts
/**
 * 存储数据
 */
export const setItem = (key: string, value: any) => {
  // value 分为两种
  // 1.基础类型
  // 2.复杂类型
  if (typeof value === 'object') {
    value = JSON.stringify(value)
  }
  window.localStorage.setItem(key, value)
}

/**
 * 获取数据
 */
export const getItem = (key: string): any => {
  try {
    const data = window.localStorage.getItem(key)
    return data != null ? JSON.parse(data) : null
  } catch (err) {
    return null
  }
}

/**
 * 删除指定数据
 */
export const removeItem = (key: string) => {
  window.localStorage.removeItem(key)
}

/**
 * 删除所有数据
 */
export const removeAllItem = () => {
  window.localStorage.clear()
}

在获取到 token 后保存

六、本地缓存处理

请求时携带 token

六、本地缓存处理

便于测试,在请求完登录接口后,直接获取一下用户信息

六、本地缓存处理

为了更直观看到结果,在 App.vue 中引用一下

六、本地缓存处理

5. 测试

登录成功之后可以看到 pinia 里存放的信息,前提是安装了 vue devtools 插件

六、本地缓存处理

localStorage 里也有我们存放的 token 信息 六、本地缓存处理

总结

至此,对于前端的缓存已经有了一个大概的雏形,还有很多细节可能暂时没有考虑到,后续开发功能的过程中如果发现问题,再进一步完善。

补充

关于持久化的问题可以使用插件完成,不用手动设置,看这里:juejin.cn/post/724964…

转载自:https://juejin.cn/post/7249627749946523707
评论
请登录