我们需要自定义一个组件,实现根据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 保存的文件会持久保存在本地,直到用户清除微信存储或小程序被删除。您可能需要定期清理旧的缓存文件。
这个组件主要适用于需要频繁加载的小型图片。对于大型图片或不常更改的图片,可能需要不同的策略。
在实际应用中,您可能还需要添加更多的错误处理和边界情况检查。
网友回复


