[外链图片转存失败(img-vbwUXXxJ-1563574134995)(https://upload-images.jianshu.io/upload_images/11158618-9e2d91116eebe601.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

<view wx:for="{{list}}" class='item item-{{index}}'
 wx:key="{{index}}">
    <image class="{{item.show ? 'active': ''}}" src="{{item.show ? item.src : item.def}}"></image>
</view>
image{
    transition: all .3s ease;
    opacity: 0;
}
.active{
    opacity: 1;
}

[外链图片转存失败(img-xPdtLwfr-1563574134999)(https://upload-images.jianshu.io/upload_images/11158618-5b01e88ab809b553.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

数据的异步加载
开始时把一部分数据加载出来,后面滚动时才对应的加载。

给需要懒加载的图片外层放置一个容器:

<div class="banner">
 <img src="" alt="" trueImg="">
</div>

.banner {
 margin: 10px auto;
 width: 350px;
 height; 200px;
 border: 1px solid green;
 background: url("../img/default.gif") no-repeat center ;
}

.banner img {
 dispaly: noene;
 width: 100%;
 height: 100%;
}

用JavaScript实现图片懒加载

new Image()来暂时存放一个图片
onload方法判断图片是否加载成功

var banner = document.querySelector('.banner');
var imgFir = banner.getElementsByTagName('img')[0];

window.setTimeout(function() {
 var oImg = new Image(); // 创建一个临时的img标签
 oImg.src = imgFir.getAttribute('trueImg');
 oImg.onload=function() { // 当图片能够正常加载就执行
 imgFir.src = this.src;
 imgFir.style.dispaly = "block";
 oImg = null;
 console.log('图片加载完成'):
 var now = new Date();
 }
 var time = new Date();
 }, 500);

懒加载技术
[外链图片转存失败(img-BTMcSqGM-1563574135001)(https://upload-images.jianshu.io/upload_images/11158618-c4d6d40acd90b397.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

[外链图片转存失败(img-HzLOj11b-1563574135003)(https://upload-images.jianshu.io/upload_images/11158618-d29542bd1e5cc00d.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

Vue实现一个图片懒加载插件
Vue.use()、Vue.direction、Vue图片懒加载插件实现

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
 // 当被绑定的元素插入到 DOM 中时……
 inserted: function (el) {
 // 聚焦元素
 el.focus()
 }
})

局部注册

directives: {
 focus: {
 // 指令的定义
 inserted: function (el) {
 el.focus()
 }
 }
}

bind:只调用一次,指令第一次绑定到元素时调用
inserted:被绑定元素插入父节点时调用
update:所在组件的 VNode 更新时调用
unbind:只调用一次

Vue图片懒加载插件实现

// 引入Vue构造函数
import Vue from 'vue'
 
var lazyload = {
 // Vue.use() 默认加载install,并且将Vue当做第一个参数传递过来
 install(vue,payload) {
 // 数组扩展移除元素
 if(!Array.prototype.remove){
 Array.prototype.remove = function(item){
 if(!this.length) return
 var index = this.indexOf(item);
 if( index > -1){
 this.splice(index,1);
 return this
 }
 }
 }
 
 // 默认值图片 
 var defaultImage = payload.defaultImage || 'https://.png';
 var errorImage = payload.errorImage || 'https://.png';
 // 默认离可视区10px时加载图片
 var distanece = payload.scrollDistance || 10;
 // 收集未加载的图片元素和资源
 var listenList = [];
 // 收集已加载的图片元素和资源
 var imageCacheList = [];
 
 // 是否已经加载完成的图片
 const isAlredyLoad = (imageSrc) => {
 if(imageCacheList.indexOf(imageSrc) > -1){
 return true;
 }else{
 return false;
 }
 }
 
 //检测图片是否可以加载,如果可以则进行加载
 const isCanShow = (item) =>{
 var ele = item.ele;
 var src = item.src;
 //图片距离页面顶部的距离
 var top = ele.getBoundingClientRect().top;
 //页面可视区域的高度
 var windowHeight = window.innerHight;
 // top - distance 距离可视区域还有distance像素
 if(top - distanece < window.innerHeight){ 
 var image = new Image();
 image.src = src;
 image.onload = function() {
 ele.src = src;
 imageCacheList.push(src);
 listenList.remove(item);
 }
 image.onerror = function() {
 ele.src = errorImage;
 imageCacheList.push(src);
 listenList.remove(item);
 }
 return true;
 }else{
 return false;
 }
 };
 
 const onListenScroll = () => {
 window.addEventListener('scroll',function(){
 var length = listenList.length;
 for(let i = 0;i<length;i++ ){
 isCanShow(listenList[i]);
 }
 })
 
 }
 
 //Vue 指令最终的方法
 const addListener = (ele,binding) =>{
 //绑定的图片地址
 var imageSrc = binding.value;
 
 // 防止重复加载。如果已经加载过,则无需重新加载,直接将src赋值
 if(isAlredyLoad(imageSrc)){ 
 ele.src = imageSrc;
 return false;
 }
 
 var item = {
 ele: ele,
 src: imageSrc
 }
 
 //图片显示默认的图片
 ele.src = defaultImage;
 
 //再看看是否可以显示此图片
 if(isCanShow(item)){
 return
 }
 
 //否则将图片地址和元素均放入监听的lisenList里
 listenList.push(item);
  
 //然后开始监听页面scroll事件
 onListenScroll();
 }
 
 Vue.directive('lazyload',{
 inserted: addListener,
 updated: addListener
 })
 }
}
 
export default lazyload;

插件的调用:

import Vue from 'vue'
import App from './App'
import router from './router'
import Lazyload from './common/js/lazyload'
 
// 参数均为可选
Vue.use(Lazyload,{
 scrollDistance: 15, // 距离可视区还有15px时开发加载资源
 defaultImage: '', // 资源图片未加载前的默认图片(绝对路径)
 errorImage:'' // 资源图片加载失败时要加载的资源(绝对路径)
})