我们需要自定义一个组件,实现根据src从本地缓冲中获取数据,没有缓冲就下载。
微信小程序提供了 wx.setStorage 和 wx.getStorage 来存储数据,以及 wx.saveFile 来保存文件。下面是一个适用于微信小程序的图片缓存组件:
<!-- components/cached-image/cached-image.wxml --> <image src="{{imageSrc}}" mode="{{mode}}" lazy-load="{{lazyLoad}}" show-menu-by-longpress="{{showMenuByLongpress}}" binderror="onImageError" bindload="onImageLoad" ></image>
// components/cached-image/cached-image.js Component({ properties: { src: { type: String, observer: function(newVal) { this.loadImage(newVal); } }, mode: { type: String, value: 'aspectFill' }, lazyLoad: { type: Boolean, value: false }, showMenuByLongpress: { type: Boolean, value: false } }, data: { imageSrc: '' }, methods: { async loadImage(url) { if (!url) return; try { // 检查缓存 const cachedPath = await this.getCachedImage(url); if (cachedPath) { this.setData({ imageSrc: cachedPath }); return; } // 下载并缓存图片 const downloadRes = await this.downloadImage(url); const savedFilePath = await this.saveFile(downloadRes.tempFilePath); await this.cacheImage(url, savedFilePath); this.setData({ imageSrc: savedFilePath }); } catch (error) { console.error('Failed to load image:', error); this.setData({ imageSrc: url }); // 如果失败,使用原始 URL } }, getCachedImage(url) { return new Promise((resolve) => { wx.getStorage({ key: url, success: (res) => { // 检查文件是否存在 wx.getSavedFileInfo({ filePath: res.data, success: () => resolve(res.data), fail: () => { // 如果文件不存在,删除存储的键 wx.removeStorage({ key: url }); resolve(null); } }); }, fail: () => resolve(null) }); }); }, downloadImage(url) { return new Promise((resolve, reject) => { wx.downloadFile({ url: url, success: resolve, fail: reject }); }); }, saveFile(tempFilePath) { return new Promise((resolve, reject) => { wx.saveFile({ tempFilePath: tempFilePath, success: (res) => resolve(res.savedFilePath), fail: reject }); }); }, cacheImage(url, filePath) { return new Promise((resolve, reject) => { wx.setStorage({ key: url, data: filePath, success: resolve, fail: reject }); }); }, onImageError(e) { this.triggerEvent('error', e.detail); }, onImageLoad(e) { this.triggerEvent('load', e.detail); } } });
使用这个组件的方法:
<!-- pages/index/index.wxml --> <cached-image src="https://example.com/image.jpg" mode="aspectFit" lazy-load="{{true}}" bind:error="handleImageError" bind:load="handleImageLoad" ></cached-image>
// pages/index/index.js Page({ handleImageError(e) { console.error('Image failed to load', e); }, handleImageLoad(e) { console.log('Image loaded successfully', e); } });
这个微信小程序版本的缓存图片组件有以下特点:
使用 wx.setStorage 和 wx.getStorage 来存储图片URL和本地文件路径的映射。使用 wx.saveFile 来将下载的临时文件保存为永久文件。在检查缓存时,会验证缓存的文件是否仍然存在。如果缓存的文件不存在,会删除相应的存储键。如果图片加载失败,会回退到使用原始URL。支持 error 和 load 事件,与原生 image 组件保持一致。注意事项:
微信小程序有存储限制,通常为10MB。您可能需要实现一个缓存清理机制,以防止超出存储限制。
wx.saveFile 保存的文件会持久保存在本地,直到用户清除微信存储或小程序被删除。您可能需要定期清理旧的缓存文件。
这个组件主要适用于需要频繁加载的小型图片。对于大型图片或不常更改的图片,可能需要不同的策略。
在实际应用中,您可能还需要添加更多的错误处理和边界情况检查。
网友回复