在移动应用开发中,本地存储是不可或缺的核心功能之一。作为跨平台开发框架,Uniapp提供了一套完善的本地存储解决方案,使开发者能够轻松实现数据的持久化存储。本文将深入探讨Uniapp本地存储的方方面面,从基础使用到高级技巧,帮助你在实际项目中高效利用这一功能。

一、本地存储的重要性与Uniapp实现

1.1 为什么需要本地存储?

在应用开发中,本地存储解决了几个关键问题:

  • 数据持久化:关闭应用后数据不会丢失

  • 离线访问:无网络时仍能获取关键数据

  • 性能优化:减少网络请求,提升用户体验

  • 状态保持:记住用户偏好和登录状态

1.2 Uniapp本地存储的特点

Uniapp的本地存储系统具有以下优势:

  • 跨平台一致性:一套API在所有平台(H5、小程序、App等)上表现一致

  • 容量更大:相比浏览器localStorage的5MB限制,Uniapp存储空间更大

  • 数据类型丰富:支持存储对象、数组等复杂数据结构

  • 同步/异步双模式:满足不同场景需求

二、Uniapp本地存储核心API详解

2.1 存储数据

异步存储(推荐在需要处理回调时使用)

uni.setStorage({
  key: 'user_profile',  // 存储键名
  data: {              // 存储数据(支持多种类型)
    name: '李四',
    age: 28,
    preferences: {
      theme: 'dark',
      fontSize: 14
    }
  },
  success: () => {
    console.log('数据存储成功');
    uni.showToast({ title: '保存成功', icon: 'success' });
  },
  fail: (err) => {
    console.error('存储失败:', err);
    uni.showToast({ title: '保存失败', icon: 'none' });
  }
});

同步存储(适合简单场景)

try {
  const settings = {
    notification: true,
    vibration: false,
    language: 'zh-CN'
  };
  uni.setStorageSync('app_settings', settings);
} catch (e) {
  console.error('同步存储失败:', e);
}

2.2 获取数据

异步获取

uni.getStorage({
  key: 'user_profile',
  success: (res) => {
    console.log('获取到的数据:', res.data);
    this.userInfo = res.data;  // 在Vue中绑定到data
  },
  fail: (err) => {
    console.error('数据获取失败:', err);
  }
});

同步获取

try {
  const settings = uni.getStorageSync('app_settings');
  if (settings) {
    this.notification = settings.notification;
    // 其他赋值操作...
  }
} catch (e) {
  console.error('同步获取失败:', e);
}

2.3 删除数据

异步删除

uni.removeStorage({
  key: 'temp_data',
  success: () => {
    console.log('数据删除成功');
  }
});

同步删除

try {
  uni.removeStorageSync('outdated_cache');
} catch (e) {
  console.error('删除失败:', e);
}

2.4 清空存储

// 异步清空(无回调)
uni.clearStorage();

// 同步清空
uni.clearStorageSync();

// 实际项目中通常会添加确认提示
function clearAllStorage() {
  uni.showModal({
    title: '警告',
    content: '确定要清除所有本地数据吗?此操作不可撤销!',
    success: (res) => {
      if (res.confirm) {
        uni.clearStorageSync();
        uni.showToast({ title: '已清除所有数据', icon: 'success' });
      }
    }
  });
}

三、高级应用技巧

3.1 存储加密

对于敏感信息(如token、用户凭证等),建议先加密再存储:

import CryptoJS from 'crypto-js';

const SECRET_KEY = 'your-secret-key-123';

// 加密存储
function setEncryptedStorage(key, data) {
  try {
    const encrypted = CryptoJS.AES.encrypt(
      JSON.stringify(data), 
      SECRET_KEY
    ).toString();
    uni.setStorageSync(key, encrypted);
    return true;
  } catch (e) {
    console.error('加密存储失败:', e);
    return false;
  }
}

// 解密获取
function getDecryptedStorage(key) {
  try {
    const encrypted = uni.getStorageSync(key);
    if (!encrypted) return null;
    
    const bytes = CryptoJS.AES.decrypt(encrypted, SECRET_KEY);
    return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
  } catch (e) {
    console.error('解密失败:', e);
    return null;
  }
}

3.2 存储过期策略

实现自动过期的存储机制:

// 带过期时间的存储
function setStorageWithExpiry(key, value, expiryDays) {
  const now = new Date();
  const item = {
    value: value,
    expiry: now.getTime() + (expiryDays * 24 * 60 * 60 * 1000)
  };
  uni.setStorageSync(key, item);
}

// 获取并检查过期
function getStorageWithExpiry(key) {
  const item = uni.getStorageSync(key);
  if (!item) return null;
  
  const now = new Date();
  if (now.getTime() > item.expiry) {
    uni.removeStorageSync(key);
    return null;
  }
  return item.value;
}

// 使用示例
setStorageWithExpiry('api_cache', apiResponse, 7); // 保存7天
const cachedData = getStorageWithExpiry('api_cache');

3.3 存储空间管理

// 估算已用存储空间
function getStorageSize() {
  let total = 0;
  const keys = uni.getStorageInfoSync().keys;
  
  keys.forEach(key => {
    const item = uni.getStorageSync(key);
    total += JSON.stringify(item).length;
  });
  
  return (total / 1024).toFixed(2) + 'KB';
}

// 清理最早存储的X条记录
function cleanupOldestItems(limit) {
  const keys = uni.getStorageInfoSync().keys;
  if (keys.length <= limit) return;
  
  // 按时间排序(需要存储时记录时间戳)
  const sortedKeys = keys.map(key => {
    return {
      key,
      time: uni.getStorageSync(key)._timestamp || 0
    };
  }).sort((a, b) => a.time - b.time);
  
  // 删除最早的
  for (let i = 0; i < sortedKeys.length - limit; i++) {
    uni.removeStorageSync(sortedKeys[i].key);
  }
}

四、性能优化与最佳实践

4.1 存储性能优化

  1. 合理分块:大数据拆分成多个key存储

    // 存储大型数组
    function saveLargeArray(key, array, chunkSize = 100) {
      for (let i = 0; i < array.length; i += chunkSize) {
        const chunk = array.slice(i, i + chunkSize);
        uni.setStorageSync(`${key}_chunk_${i/chunkSize}`, chunk);
      }
    }
  2. 避免频繁操作:合并多次存储为单次操作

  3. 使用索引:对大量数据建立索引提高查询效率

4.2 最佳实践

  1. 键名命名规范

    // 推荐使用有意义的命名空间
    const STORAGE_KEYS = {
      USER_INFO: 'app:user:info',
      SETTINGS: 'app:global:settings',
      CACHE_PREFIX: 'cache:'
    };
  2. 类型安全封装

    class TypedStorage {
      constructor(key, defaultValue, type) {
        this.key = key;
        this.default = defaultValue;
        this.type = type;
      }
      
      get() {
        const value = uni.getStorageSync(this.key);
        if (value === null || value === undefined) return this.default;
        if (typeof value !== this.type) return this.default;
        return value;
      }
      
      set(value) {
        if (typeof value !== this.type) {
          console.warn(`Invalid type for ${this.key}, expected ${this.type}`);
          return;
        }
        uni.setStorageSync(this.key, value);
      }
    }
    
    // 使用示例
    const darkMode = new TypedStorage('dark_mode', false, 'boolean');
  3. 错误处理策略

    function safeGetStorage(key, defaultValue) {
      try {
        const value = uni.getStorageSync(key);
        return value !== undefined ? value : defaultValue;
      } catch (e) {
        console.error(`获取${key}失败:`, e);
        return defaultValue;
      }
    }

五、跨平台注意事项

  1. 平台差异处理

    function setCrossPlatformStorage(key, value) {
      // 小程序端有10MB限制
      if (process.env.UNI_PLATFORM === 'mp-weixin') {
        if (JSON.stringify(value).length > 8 * 1024 * 1024) {
          console.warn('数据大小接近小程序限制');
        }
      }
      uni.setStorageSync(key, value);
    }
  2. 兼容性检查

    function checkStorageAvailable() {
      try {
        const testKey = '__storage_test__';
        uni.setStorageSync(testKey, testKey);
        uni.removeStorageSync(testKey);
        return true;
      } catch (e) {
        return false;
      }
    }

六、实际应用场景

6.1 用户登录状态维护

// 登录成功后
function handleLoginSuccess(userData, token) {
  const authData = {
    user: userData,
    token: token,
    lastLogin: new Date().getTime()
  };
  
  uni.setStorageSync('auth', authData);
  this.$store.commit('setAuth', authData); // 同步到Vuex
}

// 检查登录状态
function checkAuth() {
  const auth = uni.getStorageSync('auth');
  if (!auth || !auth.token) return false;
  
  // 检查token是否过期(假设有效期7天)
  const sevenDays = 7 * 24 * 60 * 60 * 1000;
  if (new Date().getTime() - auth.lastLogin > sevenDays) {
    uni.removeStorageSync('auth');
    return false;
  }
  
  return true;
}

6.2 应用设置持久化

// 设置管理器
const appSettings = {
  defaults: {
    theme: 'light',
    fontSize: 16,
    notifications: true
  },
  
  init() {
    const saved = uni.getStorageSync('settings') || {};
    return { ...this.defaults, ...saved };
  },
  
  save(currentSettings) {
    uni.setStorageSync('settings', currentSettings);
  },
  
  reset() {
    uni.setStorageSync('settings', this.defaults);
  }
};

// 在Vue中使用
export default {
  data() {
    return {
      settings: appSettings.init()
    };
  },
  
  watch: {
    settings: {
      deep: true,
      handler(newVal) {
        appSettings.save(newVal);
      }
    }
  }
}

6.3 列表数据缓存

// 带缓存的数据加载
async function loadDataWithCache(listType, forceRefresh = false) {
  const cacheKey = `list_cache_${listType}`;
  
  if (!forceRefresh) {
    const cached = uni.getStorageSync(cacheKey);
    if (cached) {
      const { data, timestamp } = cached;
      // 1小时内使用缓存
      if (Date.now() - timestamp < 3600000) {
        return data;
      }
    }
  }
  
  // 获取新数据
  const freshData = await fetchNewData(listType);
  uni.setStorageSync(cacheKey, {
    data: freshData,
    timestamp: Date.now()
  });
  
  return freshData;
}

总结

Uniapp的本地存储系统提供了强大而灵活的数据持久化方案。通过本文的详细介绍,你应该已经掌握了:

  1. 基础API的使用方法和同步/异步模式选择

  2. 数据加密、过期策略等高级技巧

  3. 性能优化和跨平台兼容的最佳实践

  4. 在实际项目中的典型应用场景

合理使用本地存储可以显著提升应用性能,改善用户体验,但也要注意:

  • 不要存储敏感信息(如密码、支付信息等)

  • 重要数据应该有服务器备份

  • 定期清理无用数据避免存储空间浪费

希望本指南能帮助你在Uniapp项目中更高效地使用本地存储功能,打造更出色的跨平台应用。

 

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐