uni-app实现图片第一次加载,后面直接读取缓存,只有缓存加载失败,才会在下一次重新加载图片,亲测,IOS和安卓都没问题。实现方法如下:
1、在公共js里加入下面的方法,这里主要是实现读取缓存图片和下载存储图片功能:
function getImageCache(filePath) {
// #ifdef APP-PLUS
return new Promise((resolve, reject) => {
let fileMd5 = "";
try{
// stringToBase64 是通过path给图片加个key值进行存储,具体实现方法可以百度,也可以用其他方法,如md5等实现
fileMd5 = stringToBase64(filePath)
}catch(e){
fileMd5 = filePath;
}
// 图片缓存key值
let storageKey = 'IMAGE_CACHE_INFO_' + fileMd5
// 首先获取本地存储的数据,查询是否有对应文件路径,如果有缓存内容,直接返回
const cacheFileInfo = uni.getStorageSync(storageKey)
if (cacheFileInfo) {
resolve({path: cacheFileInfo, storageKey})
return;
} else {
// console.log("未缓存,进行下载保存")
// 如果没有,执行下载,并存储起来后
uni.downloadFile({
url: filePath,
success: (res) => {
if (res.statusCode === 200) {
// console.log('下载成功',filePath,res);
// 再进行本地保存
uni.saveFile({
tempFilePath: res.tempFilePath,
success: function(res2) {
var t0 = plus.io.convertLocalFileSystemURL(res2.savedFilePath);
var t0 = res2.savedFilePath // plus.io.convertLocalFileSystemURL(res2.savedFilePath);
uni.setStorageSync(storageKey, t0)
resolve({path: t0, storageKey})
return;
},
fail: function(res2) {
resolve(filePath)
return;
}
})
} else {
console.log('下载临时文件失败')
resolve(filePath);
return;
}
},
fail: (res) => {
console.log(res)
resolve(filePath);
return;
}
})
}
})
// #endif
// #ifndef APP-PLUS
return new Promise((resolve, reject) => {
resolve(filePath);
})
// #endif
}
2、在公共components文件夹新建 cacheImage.vue 组件,用来显示图片:
<template>
<view class="wrap">
<image :src="src" :style="{width: props.width, height: props.height, borderRadius: radius}" :mode="mode" @error="imageError"></image>
</view>
</template>
<script setup>
import { watch, onBeforeMount, ref } from 'vue'
const props = defineProps({
url: {
type: String,
default: ''
},
mode: {
type: String,
default: 'widthFix'
},
width: {
type: String,
default: '200rpx'
},
height: {
type: String,
default: '200rpx'
},
radius: {
type: String,
default: '0'
}
})
const src = ref('')
let storageKey = ''
watch(() => props.info, (val) => {
console.log(val)
})
watch(() => props.url, (val) => {
getImageCache()
})
onBeforeMount(() => {
getImageCache()
})
function imageError(e,e1){
// 加载失败,并且存了缓存,说明缓存图片失效,清除缓存,下次重新加载
if(storageKey) {
uni.removeStorageSync(storageKey)
}
console.log(e,e1)
}
async function getImageCache() {
// #ifdef APP-PLUS
// 这里的 uni.$app.getImageCache 就是对上面封装的方法进行调用,存储图片
var result = await uni.$app.getImageCache(props.url)
if (result) {
src.value = result.path
storageKey = result.storageKey
} else {
src.value = props.url
}
// #endif
// #ifndef APP-PLUS
src.value = props.url
// #endif
}
</script>
3、使用
import cacheImage from '@/components/cacheImage.vue'
<cacheImage url="http://www.5imoban.net/uploadfile/2023/1105/20231105230401114.jpg"></cacheImage>