阿里云主机折上折
  • 微信号
Current Site:Index > Data caching (uni.setStorage)

Data caching (uni.setStorage)

Author:Chuan Chen 阅读数:54610人阅读 分类: uni-app

Basic Concepts of Data Caching

The uni-app framework provides the uni.setStorage method for storing data in local cache. Similar to localStorage in browser environments, it offers better cross-platform compatibility. Data caching is persistent storage, meaning the data remains available even after the user closes and reopens the app. Caching is stored in key-value pairs, with a maximum of 1MB per key and varying total cache size limits across platforms.

Basic Usage of uni.setStorage

The uni.setStorage method accepts an object parameter with two required properties:

  • key: The name of the storage key
  • data: The data to be stored
// Store a string
uni.setStorage({
  key: 'username',
  data: 'Zhang San',
  success: function() {
    console.log('Storage successful');
  }
});

// Store an object
uni.setStorage({
  key: 'userInfo',
  data: {
    name: 'Li Si',
    age: 25,
    gender: 'male'
  }
});

// Store an array
uni.setStorage({
  key: 'todoList',
  data: ['Buy groceries', 'Write code', 'Exercise']
});

Asynchronous vs. Synchronous Storage

uni-app provides both asynchronous and synchronous storage methods:

Asynchronous Storage

uni.setStorage({
  key: 'token',
  data: 'abcdef123456',
  success: () => {
    console.log('Token stored successfully');
  },
  fail: (err) => {
    console.error('Storage failed:', err);
  }
});

Synchronous Storage

try {
  uni.setStorageSync('settings', {
    theme: 'dark',
    fontSize: 14
  });
  console.log('Settings saved');
} catch (e) {
  console.error('Save failed:', e);
}

Data Type Handling

uni.setStorage can store various data types, but note the following:

  1. Primitive Types: Strings, numbers, and booleans are stored directly
uni.setStorageSync('score', 100);
uni.setStorageSync('isVIP', true);
  1. Complex Types: Objects and arrays are automatically serialized into JSON strings
const product = {
  id: 1001,
  name: 'Smartphone',
  price: 2999
};
uni.setStorageSync('currentProduct', product);
  1. Special Types: Date objects, functions, etc., need conversion first
// Store a date
const now = new Date();
uni.setStorageSync('lastLogin', now.toISOString());

// Convert back when reading
const lastLogin = new Date(uni.getStorageSync('lastLogin'));

Cache Expiration Management

Although uni-app's cache has no built-in expiration mechanism, you can implement it as follows:

// Store data with an expiration time
function setStorageWithExpire(key, data, expireDays) {
  const record = {
    data: data,
    expire: Date.now() + expireDays * 24 * 60 * 60 * 1000
  };
  uni.setStorageSync(key, record);
}

// Read and check for expiration
function getStorageWithExpire(key) {
  const record = uni.getStorageSync(key);
  if (!record) return null;
  
  if (Date.now() > record.expire) {
    uni.removeStorageSync(key);
    return null;
  }
  
  return record.data;
}

// Example usage
setStorageWithExpire('sessionToken', 'token123', 7); // Expires in 7 days
const token = getStorageWithExpire('sessionToken');

Batch Operations and Advanced Usage

Batch Data Storage

const batchData = {
  userProfile: {name: 'Wang Wu', age: 30},
  appConfig: {theme: 'light', lang: 'zh-CN'},
  recentSearches: ['uni-app', 'vue', 'mini-program']
};

Object.keys(batchData).forEach(key => {
  uni.setStorageSync(key, batchData[key]);
});

Storing Encrypted Data

// Simple encryption function
function simpleEncrypt(data, key) {
  return JSON.stringify(data).split('').map(c => 
    String.fromCharCode(c.charCodeAt(0) ^ key.charCodeAt(0))
  ).join('');
}

// Store encrypted data
const sensitiveData = {bankCard: '622588******1234'};
uni.setStorageSync('encryptedData', simpleEncrypt(sensitiveData, 'secret'));

// Decrypt when reading
const encrypted = uni.getStorageSync('encryptedData');
const decrypted = JSON.parse(simpleEncrypt(encrypted, 'secret'));

Cross-Page Data Sharing

Use caching to pass data between pages:

// Page A sends data to Page B
// Page A code
uni.setStorageSync('shareData', {
  from: 'PageA',
  timestamp: Date.now(),
  content: 'This is shared data'
});

// Page B code
onShow() {
  const shared = uni.getStorageSync('shareData');
  if (shared && shared.from === 'PageA') {
    console.log('Received shared data:', shared);
    uni.removeStorageSync('shareData'); // Clear after use
  }
}

Performance Optimization Tips

  1. Avoid Frequent Writes: Combine multiple write operations
// Not recommended
for (let i = 0; i < 100; i++) {
  uni.setStorageSync(`item_${i}`, data[i]);
}

// Recommended
const batch = {};
for (let i = 0; i < 100; i++) {
  batch[`item_${i}`] = data[i];
}
uni.setStorageSync('batchData', batch);
  1. Set Reasonable Cache Size: Monitor cache usage
function checkStorageUsage() {
  const keys = uni.getStorageInfoSync().keys;
  let total = 0;
  
  keys.forEach(key => {
    const data = uni.getStorageSync(key);
    total += JSON.stringify(data).length;
  });
  
  console.log(`Current cache usage: ${total} bytes`);
  return total;
}
  1. Regularly Clean Up Unused Cache
function cleanUpStorage() {
  const { keys } = uni.getStorageInfoSync();
  const now = Date.now();
  
  keys.forEach(key => {
    if (key.startsWith('temp_')) {
      const data = uni.getStorageSync(key);
      if (data.expire && data.expire < now) {
        uni.removeStorageSync(key);
      }
    }
  });
}

Practical Application Scenarios

Maintaining User Login Status

// After successful login
uni.setStorageSync('auth', {
  token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
  userInfo: {
    userId: '123',
    username: 'user1'
  },
  loginTime: Date.now()
});

// Check on app launch
onLaunch() {
  const auth = uni.getStorageSync('auth');
  if (auth && auth.token) {
    // Auto-login logic
    this.checkTokenValid(auth.token).then(valid => {
      if (!valid) {
        uni.removeStorageSync('auth');
        uni.redirectTo({url: '/pages/login/login'});
      }
    });
  }
}

Saving Form Drafts

// Save form draft
function saveFormDraft(formData) {
  uni.setStorage({
    key: 'draft_' + this.formId,
    data: formData,
    success: () => {
      uni.showToast({title: 'Draft saved', icon: 'success'});
    }
  });
}

// Restore form draft
function loadFormDraft() {
  const draft = uni.getStorageSync('draft_' + this.formId);
  if (draft) {
    this.formData = draft;
    uni.showModal({
      title: 'Unsubmitted draft detected',
      content: 'Restore last edit?',
      success: (res) => {
        if (!res.confirm) {
          uni.removeStorageSync('draft_' + this.formId);
        }
      }
    });
  }
}

Persisting App Configuration

// Default settings
const defaultSettings = {
  theme: 'light',
  fontSize: 16,
  notification: true
};

// Load user settings
function loadSettings() {
  const userSettings = uni.getStorageSync('userSettings') || {};
  return {...defaultSettings, ...userSettings};
}

// Save user settings
function saveSettings(settings) {
  uni.setStorageSync('userSettings', settings);
  uni.$emit('settingsChanged', settings);
}

// Listen for setting changes
uni.$on('settingsChanged', (settings) => {
  if (settings.theme === 'dark') {
    document.documentElement.classList.add('dark');
  } else {
    document.documentElement.classList.remove('dark');
  }
});

Common Issues and Solutions

Troubleshooting Storage Failures

  1. Check Key Name Validity: Avoid special characters
// Bad example
uni.setStorageSync('user-data', value); // May cause issues on some platforms

// Good example
uni.setStorageSync('userData', value);
  1. Handle Insufficient Storage Space
try {
  uni.setStorageSync('largeData', bigData);
} catch (e) {
  if (e.errMsg.includes('exceed')) {
    // Clean old cache or notify user
    cleanOldCache();
  }
}

Data Update Strategies

// Use version control to manage cached data
const CACHE_VERSION = 'v1.2';

function getCache(key) {
  const cached = uni.getStorageSync(key);
  if (cached && cached.version === CACHE_VERSION) {
    return cached.data;
  }
  return null;
}

function setCache(key, data) {
  uni.setStorageSync(key, {
    version: CACHE_VERSION,
    data: data,
    timestamp: Date.now()
  });
}

Multi-Tab Data Synchronization

// Main page code
uni.setStorageSync('sharedCount', 0);

// Listen for storage changes
uni.onStorageChange((res) => {
  if (res.key === 'sharedCount') {
    this.count = res.newValue;
  }
});

// Modify data
function increment() {
  const count = uni.getStorageSync('sharedCount') || 0;
  uni.setStorageSync('sharedCount', count + 1);
}

Platform Differences and Compatibility

Different platforms have slight variations in uni.setStorage implementation:

  1. WeChat Mini Programs:

    • 1MB max per key
    • 10MB total cache limit
    • Uses JSON.stringify serialization
  2. H5:

    • Implemented via localStorage
    • Typically 5MB total cache
    • Non-string data automatically calls toString()
  3. App:

    • iOS may have stricter limits
    • Supports larger storage space
    • Better performance than mini programs

Test code:

function testStorageLimits() {
  const testData = {data: new Array(1024 * 1024).join('a')}; // ~1MB
  
  try {
    uni.setStorageSync('sizeTest', testData);
    console.log('1MB storage test passed');
    uni.removeStorageSync('sizeTest');
  } catch (e) {
    console.warn('1MB storage test failed:', e);
  }
}

Security Considerations

  1. Handling Sensitive Information:

    • Avoid storing passwords, payment info, etc.
    • Use encryption when necessary
  2. XSS Protection:

// Escape HTML content read from cache
function safeGetHTML(key) {
  const html = uni.getStorageSync(key);
  return html.replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
  1. User Privacy Compliance:
// Provide an option to clear personal data
function clearUserData() {
  const { keys } = uni.getStorageInfoSync();
  keys.forEach(key => {
    if (key.startsWith('user_')) {
      uni.removeStorageSync(key);
    }
  });
}

Debugging Techniques

  1. View All Cache Keys
const { keys, currentSize, limitSize } = uni.getStorageInfoSync();
console.table(keys.map(key => ({
  key,
  size: JSON.stringify(uni.getStorageSync(key)).length
})));
  1. Mock Cache Data (Development Environment)
// Pre-fill test data during development
if (process.env.NODE_ENV === 'development') {
  if (!uni.getStorageSync('mockDataLoaded')) {
    uni.setStorageSync('products', [
      {id: 1, name: 'Test Product 1', price: 100},
      {id: 2, name: 'Test Product 2', price: 200}
    ]);
    uni.setStorageSync('mockDataLoaded', true);
  }
}
  1. Performance Testing
// Test storage speed
function testStorageSpeed() {
  const start = Date.now();
  const testData = {value: Array(10000).fill(0).map((_, i) => i)};
  
  for (let i = 0; i < 100; i++) {
    uni.setStorageSync(`perfTest_${i}`, testData);
  }
  
  const duration = Date.now() - start;
  console.log(`Average time for 100 stores: ${duration / 100}ms`);
  
  // Clean test data
  for (let i = 0; i < 100; i++) {
    uni.removeStorageSync(`perfTest_${i}`);
  }
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.