Skip to content

存储工具

本文档介绍浏览器存储工具的使用方法。

StorageUtils

存储工具类,封装 localStorage 和 sessionStorage,支持过期时间、加密等功能。

基础使用

typescript
import { StorageUtils } from '@vben/utils';

// 存储数据
StorageUtils.set('user', { name: '张三', age: 25 });

// 获取数据
const user = StorageUtils.get('user');

// 删除数据
StorageUtils.remove('user');

// 清空所有数据
StorageUtils.clear();

设置过期时间

typescript
import { StorageUtils } from '@vben/utils';

// 存储 1 小时后过期
StorageUtils.set('token', 'abc123', {
  expires: 3600 // 秒
});

// 获取数据(过期自动删除)
const token = StorageUtils.get('token');

使用 sessionStorage

typescript
import { StorageUtils } from '@vben/utils';

// 使用 sessionStorage
StorageUtils.set('temp', 'data', {
  storage: 'session'
});

const temp = StorageUtils.get('temp', {
  storage: 'session'
});

加密存储

typescript
import { StorageUtils } from '@vben/utils';

// 加密存储敏感数据
StorageUtils.set('password', '123456', {
  encrypt: true,
  secretKey: 'my-secret-key'
});

// 解密读取
const password = StorageUtils.get('password', {
  encrypt: true,
  secretKey: 'my-secret-key'
});

localStorage 封装

typescript
class LocalStorage {
  // 存储
  static set(key: string, value: any, expires?: number) {
    const data = {
      value,
      expires: expires ? Date.now() + expires * 1000 : null
    };
    localStorage.setItem(key, JSON.stringify(data));
  }
  
  // 获取
  static get<T = any>(key: string): T | null {
    const item = localStorage.getItem(key);
    if (!item) return null;
    
    try {
      const data = JSON.parse(item);
      
      // 检查是否过期
      if (data.expires && Date.now() > data.expires) {
        localStorage.removeItem(key);
        return null;
      }
      
      return data.value;
    } catch (error) {
      return null;
    }
  }
  
  // 删除
  static remove(key: string) {
    localStorage.removeItem(key);
  }
  
  // 清空
  static clear() {
    localStorage.clear();
  }
  
  // 获取所有键
  static keys(): string[] {
    return Object.keys(localStorage);
  }
}

完整示例

vue
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { StorageUtils } from '@vben/utils';
import { message } from 'ant-design-vue';

const storageKey = ref('');
const storageValue = ref('');
const storageExpires = ref(0);
const storageList = ref<Array<{ key: string; value: any }>>([]);

function handleSet() {
  if (!storageKey.value) {
    message.error('请输入键名');
    return;
  }
  
  try {
    StorageUtils.set(storageKey.value, storageValue.value, {
      expires: storageExpires.value || undefined
    });
    message.success('存储成功');
    loadStorageList();
  } catch (error) {
    message.error('存储失败');
  }
}

function handleGet() {
  if (!storageKey.value) {
    message.error('请输入键名');
    return;
  }
  
  const value = StorageUtils.get(storageKey.value);
  if (value !== null) {
    storageValue.value = typeof value === 'string' ? value : JSON.stringify(value);
    message.success('获取成功');
  } else {
    message.warning('数据不存在或已过期');
  }
}

function handleRemove(key: string) {
  StorageUtils.remove(key);
  message.success('删除成功');
  loadStorageList();
}

function handleClear() {
  StorageUtils.clear();
  message.success('清空成功');
  loadStorageList();
}

function loadStorageList() {
  const keys = StorageUtils.keys();
  storageList.value = keys.map(key => ({
    key,
    value: StorageUtils.get(key)
  }));
}

onMounted(() => {
  loadStorageList();
});
</script>

<template>
  <div class="storage-demo">
    <a-space direction="vertical" style="width: 100%">
      <a-input
        v-model:value="storageKey"
        placeholder="键名"
      />
      
      <a-textarea
        v-model:value="storageValue"
        placeholder="值"
        :rows="3"
      />
      
      <div>
        <span>过期时间(秒):</span>
        <a-input-number
          v-model:value="storageExpires"
          :min="0"
          placeholder="0 表示永不过期"
          style="width: 200px; margin-left: 10px"
        />
      </div>
      
      <a-space>
        <a-button type="primary" @click="handleSet">
          存储
        </a-button>
        <a-button @click="handleGet">
          获取
        </a-button>
        <a-button danger @click="handleClear">
          清空所有
        </a-button>
      </a-space>
      
      <a-divider />
      
      <h3>存储列表</h3>
      <a-list :data-source="storageList">
        <template #renderItem="{ item }">
          <a-list-item>
            <template #actions>
              <a-button
                type="link"
                danger
                size="small"
                @click="handleRemove(item.key)"
              >
                删除
              </a-button>
            </template>
            <a-list-item-meta>
              <template #title>{{ item.key }}</template>
              <template #description>
                {{ typeof item.value === 'string' ? item.value : JSON.stringify(item.value) }}
              </template>
            </a-list-item-meta>
          </a-list-item>
        </template>
      </a-list>
    </a-space>
  </div>
</template>
typescript
class CookieUtils {
  // 设置 Cookie
  static set(name: string, value: string, days?: number) {
    let expires = '';
    if (days) {
      const date = new Date();
      date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
      expires = `; expires=${date.toUTCString()}`;
    }
    document.cookie = `${name}=${value}${expires}; path=/`;
  }
  
  // 获取 Cookie
  static get(name: string): string | null {
    const nameEQ = `${name}=`;
    const ca = document.cookie.split(';');
    for (let i = 0; i < ca.length; i++) {
      let c = ca[i];
      while (c.charAt(0) === ' ') c = c.substring(1, c.length);
      if (c.indexOf(nameEQ) === 0) {
        return c.substring(nameEQ.length, c.length);
      }
    }
    return null;
  }
  
  // 删除 Cookie
  static remove(name: string) {
    this.set(name, '', -1);
  }
}

API 参考

set

存储数据。

typescript
StorageUtils.set(
  key: string,
  value: any,
  options?: {
    expires?: number;
    storage?: 'local' | 'session';
    encrypt?: boolean;
    secretKey?: string;
  }
): void

get

获取数据。

typescript
StorageUtils.get<T = any>(
  key: string,
  options?: {
    storage?: 'local' | 'session';
    encrypt?: boolean;
    secretKey?: string;
  }
): T | null

remove

删除数据。

typescript
StorageUtils.remove(
  key: string,
  options?: {
    storage?: 'local' | 'session';
  }
): void

clear

清空所有数据。

typescript
StorageUtils.clear(
  options?: {
    storage?: 'local' | 'session';
  }
): void

keys

获取所有键名。

typescript
StorageUtils.keys(
  options?: {
    storage?: 'local' | 'session';
  }
): string[]

存储限制

  • localStorage:通常 5-10MB
  • sessionStorage:通常 5-10MB
  • Cookie:每个 Cookie 最大 4KB

最佳实践

  1. 敏感数据加密存储
  2. 设置合理的过期时间
  3. 避免存储大量数据
  4. 定期清理过期数据
  5. 使用 sessionStorage 存储临时数据

参考资源

MIT License