// cached-image —— 通用图片组件:网络图经 utils/image-cache 落盘后展示(命中时零网络请求), // 本地路径(wxfile:// / http://tmp / 包内路径等)原样直出; // 未命中缓存时先骨架占位、下载完成后显示本地文件,失败自动回退网络地址,功能不受影响。 import { getCachedLocalPath, resolveImage, dropImageCache } from '../../utils/image-cache' Component({ properties: { src: { type: String, value: '' }, // 与 image 组件对齐:未显式传入时保持 scaleToFill 默认行为 mode: { type: String, value: 'scaleToFill' }, lazyLoad: { type: Boolean, value: false }, }, data: { // 实际渲染地址:本地文件路径或回退的网络地址;空串 = 骨架占位中 shown: '', }, observers: { src() { this.refresh() }, }, lifetimes: { attached() { ;(this as any)._alive = true this.refresh() }, detached() { ;(this as any)._alive = false }, }, methods: { refresh() { const src = this.data.src const seq = (((this as any)._seq as number) || 0) + 1 ;(this as any)._seq = seq if (!src) { this.setData({ shown: '' }) return } if (src.indexOf('https://') !== 0) { // 本地/包内路径直接渲染,不进入缓存流程 this.setData({ shown: src }) return } const hit = getCachedLocalPath(src) if (hit) { this.setData({ shown: hit }) return } // 未命中:先占位,下载落盘后显示本地文件(期间不渲染网络地址,避免额外请求抵消缓存收益) if (this.data.shown) this.setData({ shown: '' }) resolveImage(src).then( (localPath) => { if ((this as any)._alive === false || (this as any)._seq !== seq) return this.setData({ shown: localPath }) }, () => { if ((this as any)._alive === false || (this as any)._seq !== seq) return // 缓存不可用时回退网络地址,保证功能可用 this.setData({ shown: src }) } ) }, onImgError() { const shown = this.data.shown const src = this.data.src // 网络地址自身失败或非网络图:不再处理,避免循环回退 if (!shown || !src || shown.indexOf('https://') === 0) return ;(this as any)._seq = (((this as any)._seq as number) || 0) + 1 // 本地文件失效(被系统清理/损坏):清理缓存并回退网络地址一次 dropImageCache(src) this.setData({ shown: src }) }, }, })