介绍


开发不易,能给插件一个好评吗,拜托了!


监听scroll事件实现图片懒加载、预加载

特点:

推荐更新到最新版本



下载地址

github: https://github.com/2460392754/uniapp-tools/tree/master/lazyLoad

dcloud: https://ext.dcloud.net.cn/plugin?id=495



更新日志

https://ext.dcloud.net.cn/plugin?id=495&update_log



1.兼容性测试

✅微信小程序

✅h5

✅android

❓其他平台(没测试)



2.全局参数(setConfig)

参数列表

参数

版本

类型

必填

默认值

说明

loading


Object


加载完成之前的替代图片或者动画组件

error


Object


加载错误的替代图片或者动画组件

preLoadNum


Number

0

预加载图片,单位 px

intervalTime


Number

0

图片加载间隔(停顿)时间,单位 ms

minLoadAnimeTime


Number

0

最少过度动画时间,单位 ms

throttleTime

v1.2.2

Number

0

scroll节流时间, 单位 ms


loading、error对象参数列表

参数

类型

必填

说明

loading.type、error.type

String

类型,合法值: component、img

loading.name、error.name

String

组件名称

loading.path、error.path

String

图片路径


如何配置

或者封装成文件导入

// main.js

import lazyLoadPlugin from './plugins/lazyLoad/js/lazyLoad'

lazyLoadPlugin.setConfig({
    loading: {  // 加载完成之前的替代图片或者动画组件
        type: 'component',
        name: 'loading-1'
    },
    // loading: {
    //     type: 'img',
    //     path: '/static/loading.png'
    // },
    // error: {  // 加载错误的替代图片或者动画组件
    //     type: 'img',
    //     path: '/static/error_1.png'
    // },
    error: {
        type: 'component',
        name: 'error-1'
    },
    preLoadNum: 100, // 预加载图片,单位 px
    intervalTime: 500, // 图片加载间隔(停顿)时间,单位 ms
    minLoadAnimeTime: 1000, // 最少过度动画时间,单位 ms
    throttleTime: 200 // 节流时间, 单位 ms
})



4.自定义动画组件配置

由于小程序的系统限制,没法动态插入vue组件,所以动画组件配置可能有点麻烦。不喜欢的,也可以直接使用图片+css3替代。


components目录结构

hBuilderX\lazyLoad\components
└── lazyLoad
    ├── animation
    │   ├── error-1.vue
    │   ├── errorExport.vue
    │   ├── loading-1.vue
    │   └── loadingExport.vue
    └── index.vue


例: loading动画组件配置

type的值就是setConfig中填写的组件名称

// loadingExport.vue

<template>
    <view>
        <loading1 v-if="type === 'loading-1'"></loading1>
    </view>
</template>

<script>
import loading1 from './loading-1.vue';

export default {
    props: {
        type: String
    },

    components: {
        loading1
    }
}
</script>

<style>
</style>



5.如何使用

引入config.js

// main.js

// do somethind...
import './plugins/lazyLoad/js/config.js'
// do somethind...


scroll事件

<template>
    <view>
        <scroll-view :scroll-y="true"
                     @scroll="scroll"
                     id="scroll">
            <!-- not exists img -->
            <view class='item'>
                <v-lazyload :src="'/static/dog/1123123.jpg'"
                            mode="widthFix"></v-lazyload>
            </view>

            <view v-for="n of 6"
                  :key="n"
                  class='item'>
                <v-lazyload :src="'/static/dog/'+n+'.jpg'"
                            mode="widthFix"></v-lazyload>
            </view>

            <!-- not exists img -->
            <view class='item'>
                <v-lazyload :src="'/static/dog/11231xasxasx23.jpg'"
                            mode="widthFix"></v-lazyload>
            </view>
        </scroll-view>
    </view>
</template>

<script>
import VLazyload from "@/components/lazyLoad/index.vue";
import lazyLoadPlugin from '@/plugins/lazyLoad/js/lazyLoad.js'

export default {
    methods: {
        scroll () {
            // 监听scroll事件
            lazyLoadPlugin.scroll();
        }
    },

    components: {
        VLazyload,
    },

    mounted () {
        // 初始化配置, scroll-view标签id, 第二个参数默认为false,横向懒加载,需要为 true
        lazyLoadPlugin.init('#scroll')
    },

    destroyed () {
        // 监听页面卸载
        lazyLoadPlugin.destroy();
    }
}
</script>

<style>
#scroll {
    height: 100vh; /* 需要给scroll-view设置高度 */
    background: #f8f8f9;
}

/* #ifdef H5*/
#scroll >>> .img-lazyLoad .load-img {
    width: calc(100vw - 80px);
    height: 100px;
    border-radius: 10px;
}

#scroll >>> .img-lazyLoad .load-error-img {
    width: 100px;
}
/* #endif */

/* #ifndef H5*/
#scroll .img-lazyLoad .load-img {
    width: calc(100vw - 80px);
    height: 100px;
    border-radius: 10px;
}

#scroll .img-lazyLoad .load-error-img {
    width: 100px;
}
/* #endif */

#scroll .img-lazyLoad .load-error-img {
    width: 100px;
}

.item {
    background: #fff;
    width: fit-content;
    padding: 20px;
    margin: 20px;
    border-radius: 10px;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
    width: calc(100vw - 80px);
    /* min-height: 200px; */
}
</style>


原生事件

<template>
    <view class='page'
          id="scroll">
        <view v-for="n of 6"
              :key="n"
              class='item'>
            <v-lazyload :src="'/static/dog/'+n+'.jpg'"
                        mode="widthFix"></v-lazyload>
        </view>
    </view>
</template>

<script>
import lazyLoadPlugin from '@/plugins/lazyLoad/js/lazyLoad.js'
import VLazyload from "@/components/lazyLoad/index.vue";

export default {
    onPageScroll () {
        lazyLoadPlugin.scroll();
    },

    mounted () {
        lazyLoadPlugin.init('#scroll')
    },

    destroyed () {
        // 监听页面卸载
        lazyLoadPlugin.destroy();
    },

    components: {
        VLazyload,
    },
}
</script>

<style>
#scroll {
    height: 100vh; /* 需要给scroll-view设置高度 */
    background: #f8f8f9;
}

/* #ifdef H5*/
.page >>> .img-lazyLoad .load-img {
    width: calc(100vw - 80px);
    height: 100px;
    border-radius: 10px;
}

.page >>> .img-lazyLoad .load-error-img {
    width: 100px;
}
/* #endif */

/* #ifndef H5*/
.page .img-lazyLoad .load-img {
    width: calc(100vw - 80px);
    height: 100px;
    border-radius: 10px;
}

.page .img-lazyLoad .load-error-img {
    width: 100px;
}
/* #endif */

.item {
    background: #fff;
    width: fit-content;
    padding: 20px;
    margin: 20px;
    border-radius: 10px;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
    width: calc(100vw - 80px);
    /* min-height: 200px; */
}
</style>



选项卡切换

v1.2.3新增

选项卡的切换方式必须是v-show

需要lazyload的组件scrollid和它祖父级的scroll标签id设置一样

关于切换失效或者其他问题,请查看 示例项目 中的 '@/components/nav.vue' 这个组件和 '@/pages/horizontal/nav.vue' 这个页面 源码

<template>
    <view class='nav-page'>
        <v-nav :name="nav"
               :change="change">

            <!-- tab-0 -->
            <view v-show="cur === 0">
                <scroll-view :scroll-y="true"
                             @scroll="scroll"
                             id="scroll-0">
                    <view v-for="n of 6"
                          :key="n"
                          class='item'>
                        <v-lazyload scrollid="scroll-0"
                                    mode="widthFix"
                                    :src="'/static/dog/'+n+'.jpg'"></v-lazyload>
                    </view>
                </scroll-view>
            </view>

            <!-- tab-1 -->
            <view v-show="cur === 1">
                <scroll-view :scroll-y="true"
                             @scroll="scroll"
                             id="scroll-1">
                    <view v-for="n of 3"
                          :key="n"
                          class='item'>
                        <v-lazyload :src="'/static/cat/'+n+'.jpg'"
                                    scrollid="scroll-1"
                                    mode="widthFix"></v-lazyload>
                    </view>
                </scroll-view>
            </view>

        </v-nav>
    </view>
</template>

<script>
import VNav from '@/components/nav'
import VLazyload from "@/components/lazyLoad/index.vue";
import lazyLoadPlugin from '@/plugins/lazyLoad/js/lazyLoad.js'

export default {
    data () {
        return {
            nav: [
                'tab - 0',
                'tab - 1'
            ],
            cur: 0
        }
    },

    methods: {
        change (i) {
            // console.log('is change', i)
            this.cur = i;


            // 切换 scroll标签id
            lazyLoadPlugin.setScrollId('#scroll-' + i);
        },

        scroll () {
            lazyLoadPlugin.scroll();
        }
    },

    mounted () {
        // 初始化配置, scroll-view标签id, 第二个参数默认为false,横向懒加载,需要为 true
        lazyLoadPlugin.init('#scroll-0', false)
    },

    destroyed () {
        // 监听页面卸载
        lazyLoadPlugin.destroy();
    },

    components: {
        VNav,
        VLazyload
    }
}
</script>

<style>
.nav-page {
    background: #f8f8f9;
}

#scroll-0,
#scroll-1 {
    height: 100vh; /* 需要给scroll-view设置高度 */
    background: #f8f8f9;
}

/* #ifdef H5*/
.nav-page >>> .img-lazyLoad .load-img {
    width: calc(100vw - 80px);
    height: 100px;
    border-radius: 10px;
}

.nav-page >>> .img-lazyLoad .load-error-img {
    width: 100px;
}
/* #endif */

/* #ifndef H5*/
.nav-page .img-lazyLoad .load-img {
    width: calc(100vw - 80px);
    height: 100px;
    border-radius: 10px;
}

.nav-page .img-lazyLoad .load-error-img {
    width: 100px;
}
/* #endif */

.nav-page .img-lazyLoad .load-error-img {
    width: 100px;
}

.item {
    background: #fff;
    width: fit-content;
    padding: 20px;
    margin: 20px;
    border-radius: 10px;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
    width: calc(100vw - 80px);
    /* min-height: 200px; */
}
</style>



6.问题

Q:懒加载组件中的图片样式如何设置

A:请查看上面demo中style标签的设置,或者查看源码也行


Q: 小程序平台或者其他平台中,懒组件被2次封装后图片样式设置不生效

A: 在pages文件夹中的页面中设置样式


Q: scroll和懒组件被封装后导致抛出异常"scroll样式id错误或未能获取当前属性"

A: 修改组件的上下文(v1.2.4更新)

lazyLoadPlugin.init('#scroll', false, { ctx: this })



最后

出现bug了?

遇到无法解决的问题?

直接加我q或者发邮件也行


email: 2460392754@qq.com

qq: 2460392754


欢迎交流或探讨问题!