微信小程序图片预加载-组件式写法
微信小程序图片预加载不能用wx.getImageInfo获取图片信息,因为用wx.getImageInfo控制台network走的是xhr类型,xhr加载的图片,不算预加载。 所以image应该走的是png/jpg/gif类型
封装的预加载图片组件preload-images
index.wxml
<view class="container">
<view wx:for="{{images}}" wx:for-item="image" wx:for-index="index" wx:key="index" class="image-wrapper" hidden="{{image.isHidden}}">
<image src="{{image.src}}" bindload="onLoad" binderror="onError" data-index="{{index}}" />
</view>
<view class="status-text">{{status}}</view>
</view>
index.js
Component({
properties: {
images: {
type: Array,
value: [],
},
},
data: {
status: '',
loadedImagesCount: 0,
errorImages: [],
},
lifetimes: {
attached() {
this.initializeHiddenStatus();
},
},
methods: {
initializeHiddenStatus() {
if (this.data.images.length === 0) return;
const newImages = this.data.images.map((url) => ({
src: url,
isHidden: true,
}));
this.setData({
images: newImages,
status: '加载中...',
});
},
updateStatus() {
if (this.data.loadedImagesCount === this.data.images.length) {
this.setData({ status: '加载完成' });
this.triggerEvent('complete', { images: this.data.images, errorImages: this.data.errorImages });
} else {
this.setData({ status: `已加载 ${this.data.loadedImagesCount} / ${this.data.images.length}` });
this.triggerEvent('process', `${parseInt((this.data.loadedImagesCount / this.data.images.length) * 100)}`);
}
},
onLoad(e) {
const index = e.currentTarget.dataset.index;
this.data.images[index].isHidden = false;
this.data.loadedImagesCount += 1;
this.updateStatus();
this.triggerEvent('load', e);
},
onError(e) {
const index = e.currentTarget.dataset.index;
this.data.errorImages.push(this.data.images[index]);
this.data.loadedImagesCount += 1;
this.updateStatus();
this.triggerEvent('error', {
event: e,
image: this.data.images[index],
errorImages: this.data.errorImages,
});
},
},
});
index.wxss
/* components/preload-images/index.wxss */
.preloadContainer {
display: flex;
flex-wrap: wrap;
position: absolute;
left: -999999rpx;
opacity: 0;
}
.image-wrapper {
width: 33.33%; /* 调整图片显示大小和数量 */
padding: 5px;
}
.image-wrapper image {
width: 100%;
height: auto;
}
.status-text {
width: 100%;
margin-top: 10px;
text-align: center;
}
页面使用
test.wxml
<!-- 图片预加载 --> <preload-images wx:if="{{imageUrls.length > 0}}" images="{{imageUrls}}" bind:load="imgLoad" bind:complete="imgComplete" bind:process="imgProcess" bind:error="imgError"></preload-images>
test.js
const imageList = require("../../../utils/imageList.js");
const imagePreloader = require("../../../utils/image_preloader.js");
Page({
/**
* 页面的初始数据
*/
data: {
imageUrls: [],
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.initImgLoading();
},
// 预加载图片 three 图片文件夹
initImgLoading() {
const allImageUrls = imagePreloader.getAllImageUrls(imageList.images["three"]);
this.setData({
imageUrls: allImageUrls,
});
},
imgLoad(e) {
//console.log("加载中", e)
},
imgProcess(e) {
console.log("图片加载进度");
let { detail } = e;
},
imgComplete(e) {
console.log("图片预加载成功", e);
},
imgError(e) {
console.log(e, "==图片加载错误");
},
});
utils
image_preloader.js
对图片做拼接处理
function preloadImages(imageUrls, onProgress) {
let loadedCount = 0;
const totalCount = imageUrls.length;
return Promise.all(
imageUrls.map(url =>
new Promise((resolve, reject) => {
wx.getImageInfo({
src: url,
success: () => {
loadedCount++;
onProgress((loadedCount / totalCount) * 100);
resolve(url);
},
fail: () => {
loadedCount++;
onProgress((loadedCount / totalCount) * 100);
reject(url);
},
});
})
)
);
}
function getAllImageUrls(images) {
const urls = [];
for (const key in images) {
if (Array.isArray(images[key])) {
urls.push(...images[key]);
} else {
urls.push(...getAllImageUrls(images[key]));
}
}
return urls;
}
module.exports = {
preloadImages: preloadImages,
getAllImageUrls: getAllImageUrls,
};
imageList.js
配置图片路径
const app = getApp();
const { globalData } = app;
const prefix = globalData.imgCDN; // 图片的cdn
const version = globalData.mathRom;//图片的版本号,用来清缓存
const imageFilenames = {
three: {
loading: ["bg.jpg", "i1.png", "logo.png"],
},
};
function addPrefixToImages(obj, prefix, version) {
const result = {};
for (const key in obj) {
if (Array.isArray(obj[key])) {
result[key] = obj[key].map((filename) => prefix + key + "/" + filename + "?v=" + version);
} else {
result[key] = addPrefixToImages(obj[key], prefix + key + "/", version);
}
}
return result;
}
const images = addPrefixToImages(imageFilenames, prefix, version);
module.exports = {
images: images,
};